Reverse Engineering Asked by Jimmy.D on September 27, 2021
This is my first time doing RE on a statically linked and stripped binary with ghidra. And I’m having a really hard time analyzing what function does what just by looking the decompiled code present by ghidra.
Ghidra recognised the binary language ID as ARM:LE:32:v8
and I’m especially stuck on this function:
undefined8 ToSolve1(uint *param_1,uint *param_2,int param_3,uint param_4)
{
uint *puVar1;
uint *puVar2;
byte *pbVar3;
byte *pbVar4;
uint *puVar5;
uint *puVar6;
byte *pbVar7;
int iVar8;
int iVar9;
int iVar10;
byte bVar11;
uint uVar12;
uint uVar13;
uint uVar14;
uint uVar15;
uint uVar16;
bool bVar17;
bool bVar18;
if (param_2 < param_1) {
param_2 = (uint *)((int)param_2 + param_3);
param_1 = (uint *)((int)param_1 + param_3);
iVar8 = param_3 + -4;
iVar10 = iVar8;
if (param_3 < 4) goto LAB_0003ba2c;
uVar13 = (uint)param_1 & 3;
if (uVar13 != 0) {
bVar11 = *(byte *)(uint *)((int)param_2 + -1);
*(byte *)(uint *)((int)param_1 + -1) = bVar11;
puVar2 = (uint *)((int)param_1 + -1);
puVar1 = (uint *)((int)param_2 + -1);
if (1 < uVar13) {
bVar11 = *(byte *)(uint *)((int)param_2 + -2);
*(byte *)(uint *)((int)param_1 + -2) = bVar11;
puVar2 = (uint *)((int)param_1 + -2);
puVar1 = (uint *)((int)param_2 + -2);
}
param_2 = puVar1;
param_1 = puVar2;
if (2 < uVar13) {
param_2 = (uint *)((int)param_2 + -1);
bVar11 = *(byte *)param_2;
}
param_4 = (uint)bVar11;
if (2 < uVar13) {
param_1 = (uint *)((int)param_1 + -1);
*(byte *)param_1 = bVar11;
}
iVar10 = iVar8 - uVar13;
bVar17 = iVar8 < (int)uVar13;
iVar8 = iVar10;
if (bVar17) goto LAB_0003ba2c;
}
uVar13 = (uint)param_2 & 3;
if (uVar13 == 0) {
iVar9 = iVar8 + -8;
if (7 < iVar8) {
iVar8 = iVar8 + -0x1c;
iVar10 = iVar8;
if (0x13 < iVar9) {
do {
uVar16 = param_2[-2];
uVar14 = param_2[-3];
uVar13 = param_2[-4];
param_1[-1] = param_2[-1];
param_1[-2] = uVar16;
param_1[-3] = uVar14;
param_1[-4] = uVar13;
puVar2 = param_2 + -5;
uVar14 = param_2[-6];
uVar13 = param_2[-7];
param_2 = param_2 + -8;
param_4 = *param_2;
param_1[-5] = *puVar2;
param_1[-6] = uVar14;
param_1[-7] = uVar13;
param_1 = param_1 + -8;
*param_1 = param_4;
iVar8 = iVar10 + -0x20;
bVar17 = 0x1f < iVar10;
iVar10 = iVar8;
} while (bVar17);
}
if (iVar8 + 0x10 < 0 == SCARRY4(iVar8,0x10)) {
puVar2 = param_2 + -1;
uVar14 = param_2[-2];
uVar13 = param_2[-3];
param_2 = param_2 + -4;
param_4 = *param_2;
param_1[-1] = *puVar2;
param_1[-2] = uVar14;
param_1[-3] = uVar13;
param_1 = param_1 + -4;
*param_1 = param_4;
iVar8 = iVar8 + -0x10;
}
iVar9 = iVar8 + 0x14;
if (iVar9 < 0 == SCARRY4(iVar8,0x14)) {
puVar2 = param_2 + -1;
uVar13 = param_2[-2];
param_2 = param_2 + -3;
param_4 = *param_2;
param_1[-1] = *puVar2;
param_1[-2] = uVar13;
param_1 = param_1 + -3;
*param_1 = param_4;
iVar9 = iVar8 + 8;
}
}
iVar10 = iVar9 + 8;
if (iVar10 < 0 == SCARRY4(iVar9,8)) {
if (iVar10 < 4) {
param_2 = param_2 + -1;
param_4 = *param_2;
}
if (iVar9 + 4 < 0 == SBORROW4(iVar10,4)) {
puVar2 = param_2 + -1;
param_2 = param_2 + -2;
uVar13 = *param_2;
param_1[-1] = *puVar2;
param_1 = param_1 + -2;
*param_1 = uVar13;
iVar10 = iVar9;
}
else {
param_1 = param_1 + -1;
*param_1 = param_4;
iVar10 = iVar9 + 4;
}
}
goto LAB_0003ba2c;
}
param_2 = (uint *)((uint)param_2 & 0xfffffffc);
uVar14 = *param_2;
if (1 < uVar13) {
if (uVar13 == 2) {
if (iVar8 < 0xc) {
LAB_0003bb4c:
do {
uVar13 = uVar14 << 0x10;
param_2 = param_2 + -1;
uVar14 = *param_2;
param_1 = param_1 + -1;
*param_1 = uVar13 | uVar14 >> 0x10;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 << 0x10;
uVar15 = param_2[-1];
uVar12 = param_2[-2];
uVar16 = param_2[-3];
param_2 = param_2 + -4;
uVar14 = *param_2;
param_1[-1] = uVar13 | uVar15 >> 0x10;
param_1[-2] = uVar15 << 0x10 | uVar12 >> 0x10;
param_1[-3] = uVar12 << 0x10 | uVar16 >> 0x10;
param_1 = param_1 + -4;
*param_1 = uVar16 << 0x10 | uVar14 >> 0x10;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003bb4c;
}
param_2 = (uint *)((int)param_2 + 2);
goto LAB_0003ba2c;
}
if (iVar8 < 0xc) {
LAB_0003bae0:
do {
uVar13 = uVar14 << 8;
param_2 = param_2 + -1;
uVar14 = *param_2;
param_1 = param_1 + -1;
*param_1 = uVar13 | uVar14 >> 0x18;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 << 8;
uVar15 = param_2[-1];
uVar12 = param_2[-2];
uVar16 = param_2[-3];
param_2 = param_2 + -4;
uVar14 = *param_2;
param_1[-1] = uVar13 | uVar15 >> 0x18;
param_1[-2] = uVar15 << 8 | uVar12 >> 0x18;
param_1[-3] = uVar12 << 8 | uVar16 >> 0x18;
param_1 = param_1 + -4;
*param_1 = uVar16 << 8 | uVar14 >> 0x18;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003bae0;
}
param_2 = (uint *)((int)param_2 + 3);
goto LAB_0003ba2c;
}
if (iVar8 < 0xc) {
LAB_0003bbb8:
do {
uVar13 = uVar14 << 0x18;
param_2 = param_2 + -1;
uVar14 = *param_2;
param_1 = param_1 + -1;
*param_1 = uVar13 | uVar14 >> 8;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 << 0x18;
uVar15 = param_2[-1];
uVar12 = param_2[-2];
uVar16 = param_2[-3];
param_2 = param_2 + -4;
uVar14 = *param_2;
param_1[-1] = uVar13 | uVar15 >> 8;
param_1[-2] = uVar15 << 0x18 | uVar12 >> 8;
param_1[-3] = uVar12 << 0x18 | uVar16 >> 8;
param_1 = param_1 + -4;
*param_1 = uVar16 << 0x18 | uVar14 >> 8;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003bbb8;
}
param_2 = (uint *)((int)param_2 + 1);
LAB_0003ba2c:
iVar8 = iVar10 + 4;
if (iVar8 != 0) {
bVar18 = SBORROW4(iVar8,2);
bVar17 = iVar10 + 2 < 0;
pbVar7 = (byte *)((int)param_2 + -1);
bVar11 = *pbVar7;
pbVar3 = (byte *)((int)param_1 + -1);
*pbVar3 = bVar11;
if (1 < iVar8) {
pbVar7 = (byte *)((int)param_2 + -2);
bVar11 = *pbVar7;
}
if (bVar17 == bVar18) {
pbVar3 = (byte *)((int)param_1 + -2);
*pbVar3 = bVar11;
}
if (iVar8 != 2 && bVar17 == bVar18) {
pbVar7 = pbVar7 + -1;
bVar11 = *pbVar7;
}
if (iVar8 != 2 && bVar17 == bVar18) {
pbVar3 = pbVar3 + -1;
*pbVar3 = bVar11;
}
return CONCAT44(pbVar3,pbVar7);
}
return CONCAT44(param_1,param_2);
}
if (param_2 == param_1) {
return CONCAT44(param_1,param_2);
}
iVar8 = param_3 + -4;
puVar2 = param_1;
iVar10 = iVar8;
if (param_3 < 4) goto LAB_0003b7ec;
if (((uint)param_1 & 3) == 0) {
uVar13 = (uint)param_2 & 3;
puVar1 = param_1;
}
else {
iVar10 = -((uint)param_1 & 3);
iVar9 = iVar10 + 4;
bVar18 = SBORROW4(iVar9,2);
bVar17 = iVar10 + 2 < 0;
bVar11 = *(byte *)param_2;
*(byte *)param_1 = bVar11;
puVar2 = (uint *)((int)param_2 + 1);
if (1 < iVar9) {
puVar2 = (uint *)((int)param_2 + 2);
bVar11 = *(byte *)(uint *)((int)param_2 + 1);
}
puVar1 = (uint *)((int)param_1 + 1);
if (bVar17 == bVar18) {
puVar1 = (uint *)((int)param_1 + 2);
*(byte *)(uint *)((int)param_1 + 1) = bVar11;
}
param_2 = puVar2;
if (iVar9 != 2 && bVar17 == bVar18) {
param_2 = (uint *)((int)puVar2 + 1);
bVar11 = *(byte *)puVar2;
}
param_4 = (uint)bVar11;
puVar2 = puVar1;
if (iVar9 != 2 && bVar17 == bVar18) {
puVar2 = (uint *)((int)puVar1 + 1);
*(byte *)puVar1 = bVar11;
}
iVar10 = iVar8 - iVar9;
if (iVar8 < iVar9) goto LAB_0003b7ec;
uVar13 = (uint)param_2 & 3;
iVar8 = iVar10;
puVar1 = puVar2;
}
if (uVar13 == 0) {
iVar9 = iVar8 + -8;
if (7 < iVar8) {
iVar8 = iVar8 + -0x1c;
if (0x13 < iVar9) {
do {
iVar10 = iVar8;
puVar5 = param_2;
puVar2 = puVar1;
uVar13 = puVar5[1];
uVar14 = puVar5[2];
uVar16 = puVar5[3];
*puVar2 = *puVar5;
puVar2[1] = uVar13;
puVar2[2] = uVar14;
puVar2[3] = uVar16;
param_4 = puVar5[4];
uVar13 = puVar5[5];
uVar14 = puVar5[6];
uVar16 = puVar5[7];
param_2 = puVar5 + 8;
puVar2[4] = param_4;
puVar2[5] = uVar13;
puVar2[6] = uVar14;
puVar2[7] = uVar16;
puVar1 = puVar2 + 8;
iVar8 = iVar10 + -0x20;
} while (0x1f < iVar10);
if (iVar10 + -0x10 < 0 == SCARRY4(iVar8,0x10)) {
param_4 = *param_2;
uVar13 = puVar5[9];
uVar14 = puVar5[10];
uVar16 = puVar5[0xb];
param_2 = puVar5 + 0xc;
*puVar1 = param_4;
puVar2[9] = uVar13;
puVar2[10] = uVar14;
puVar2[0xb] = uVar16;
puVar1 = puVar2 + 0xc;
iVar8 = iVar10 + -0x30;
}
}
bVar18 = SCARRY4(iVar8,0x14);
iVar9 = iVar8 + 0x14;
bVar17 = iVar9 < 0;
do {
if (bVar17 == bVar18) {
param_4 = *param_2;
uVar13 = param_2[1];
uVar14 = param_2[2];
param_2 = param_2 + 3;
*puVar1 = param_4;
puVar1[1] = uVar13;
puVar1[2] = uVar14;
puVar1 = puVar1 + 3;
bVar18 = SBORROW4(iVar9,0xc);
iVar9 = iVar9 + -0xc;
bVar17 = iVar9 < 0;
}
} while (bVar17 == bVar18);
}
iVar10 = iVar9 + 8;
puVar2 = puVar1;
if (iVar10 < 0 == SCARRY4(iVar9,8)) {
if (iVar10 < 4) {
param_4 = *param_2;
param_2 = param_2 + 1;
}
if (iVar9 + 4 < 0 == SBORROW4(iVar10,4)) {
uVar13 = *param_2;
uVar14 = param_2[1];
param_2 = param_2 + 2;
*puVar1 = uVar13;
puVar1[1] = uVar14;
puVar2 = puVar1 + 2;
iVar10 = iVar9;
}
else {
puVar2 = puVar1 + 1;
*puVar1 = param_4;
iVar10 = iVar9 + 4;
}
}
goto LAB_0003b7ec;
}
puVar5 = (uint *)((uint)param_2 & 0xfffffffc) + 1;
uVar14 = *(uint *)((uint)param_2 & 0xfffffffc);
if (uVar13 < 3) {
if (uVar13 == 2) {
puVar6 = puVar5;
if (iVar8 < 0xc) {
LAB_0003b910:
do {
uVar13 = uVar14 >> 0x10;
puVar5 = puVar6 + 1;
uVar14 = *puVar6;
puVar2 = puVar1 + 1;
*puVar1 = uVar13 | uVar14 << 0x10;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
puVar1 = puVar2;
puVar6 = puVar5;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 >> 0x10;
uVar16 = *puVar5;
uVar12 = puVar5[1];
uVar15 = puVar5[2];
uVar14 = puVar5[3];
puVar5 = puVar5 + 4;
*puVar1 = uVar13 | uVar16 << 0x10;
puVar1[1] = uVar16 >> 0x10 | uVar12 << 0x10;
puVar1[2] = uVar12 >> 0x10 | uVar15 << 0x10;
puVar1[3] = uVar15 >> 0x10 | uVar14 << 0x10;
puVar1 = puVar1 + 4;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
puVar2 = puVar1;
puVar6 = puVar5;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003b910;
}
param_2 = (uint *)((int)puVar5 + -2);
goto LAB_0003b7ec;
}
puVar6 = puVar5;
if (iVar8 < 0xc) {
LAB_0003b8a4:
do {
uVar13 = uVar14 >> 8;
puVar5 = puVar6 + 1;
uVar14 = *puVar6;
puVar2 = puVar1 + 1;
*puVar1 = uVar13 | uVar14 << 0x18;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
puVar1 = puVar2;
puVar6 = puVar5;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 >> 8;
uVar16 = *puVar5;
uVar12 = puVar5[1];
uVar15 = puVar5[2];
uVar14 = puVar5[3];
puVar5 = puVar5 + 4;
*puVar1 = uVar13 | uVar16 << 0x18;
puVar1[1] = uVar16 >> 8 | uVar12 << 0x18;
puVar1[2] = uVar12 >> 8 | uVar15 << 0x18;
puVar1[3] = uVar15 >> 8 | uVar14 << 0x18;
puVar1 = puVar1 + 4;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
puVar2 = puVar1;
puVar6 = puVar5;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003b8a4;
}
param_2 = (uint *)((int)puVar5 + -3);
goto LAB_0003b7ec;
}
puVar6 = puVar5;
if (iVar8 < 0xc) {
LAB_0003b97c:
do {
uVar13 = uVar14 >> 0x18;
puVar5 = puVar6 + 1;
uVar14 = *puVar6;
puVar2 = puVar1 + 1;
*puVar1 = uVar13 | uVar14 << 8;
iVar10 = iVar8 + -4;
bVar17 = 3 < iVar8;
puVar1 = puVar2;
puVar6 = puVar5;
iVar8 = iVar10;
} while (bVar17);
}
else {
iVar8 = iVar8 + -0xc;
do {
iVar9 = iVar8;
uVar13 = uVar14 >> 0x18;
uVar16 = *puVar5;
uVar12 = puVar5[1];
uVar15 = puVar5[2];
uVar14 = puVar5[3];
puVar5 = puVar5 + 4;
*puVar1 = uVar13 | uVar16 << 8;
puVar1[1] = uVar16 >> 0x18 | uVar12 << 8;
puVar1[2] = uVar12 >> 0x18 | uVar15 << 8;
puVar1[3] = uVar15 >> 0x18 | uVar14 << 8;
puVar1 = puVar1 + 4;
iVar8 = iVar9 + -0x10;
} while (0xf < iVar9);
iVar10 = iVar9 + -4;
puVar2 = puVar1;
puVar6 = puVar5;
iVar8 = iVar10;
if (iVar10 < 0 == SCARRY4(iVar9 + -0x10,0xc)) goto LAB_0003b97c;
}
param_2 = (uint *)((int)puVar5 + -1);
LAB_0003b7ec:
iVar8 = iVar10 + 4;
if (iVar8 != 0) {
bVar18 = SBORROW4(iVar8,2);
bVar17 = iVar10 + 2 < 0;
bVar11 = *(byte *)param_2;
*(byte *)puVar2 = bVar11;
pbVar3 = (byte *)((int)param_2 + 1);
if (1 < iVar8) {
pbVar3 = (byte *)((int)param_2 + 2);
bVar11 = *(byte *)((int)param_2 + 1);
}
pbVar7 = (byte *)((int)puVar2 + 1);
if (bVar17 == bVar18) {
pbVar7 = (byte *)((int)puVar2 + 2);
*(byte *)((int)puVar2 + 1) = bVar11;
}
pbVar4 = pbVar3;
if (iVar8 != 2 && bVar17 == bVar18) {
pbVar4 = pbVar3 + 1;
bVar11 = *pbVar3;
}
if (iVar8 != 2 && bVar17 == bVar18) {
*pbVar7 = bVar11;
}
return CONCAT44(param_1,pbVar4);
}
return CONCAT44(param_1,param_2);
}
My best guess for now is it is doing some kind of encoding and it might be a standard glibc function as it is called many times throughout the code.
This function is usally called with parameter like follows:
ToSolve1(auStack55,(uint *)&DAT_000543f4,0xe,uVar10);
ToSolve1(auStack55,(uint *)&DAT_0005489c,0xe,uVar10);
ToSolve1((uint *)&DAT_0004f602,&local_1c,4,(uint)&DAT_0004f680);
ToSolve1(param_1,&DAT_0004f5f8,0xe,(uint)puVar4);
Hope someone can give me a nudge on what this function is.
If possible, I would like to learn about if there are any resources out there that can help me improve the skills of recognizing standard function signatures.
For starters you could start by geting rid of most of the casts then start carving out the stack and heap structs where possible, then try to change the name of variables where possible to more type oriented ones, this will show most of the "duplicate" variables.
Then start following the main flow following labels and maybe change their name to what specific position mignt represet, like fail_exit
or success_exit
etc
Allso, is allways good to have the basic std structs defined if the source was compiled with c++.
e.g
struct std_vector{
void* begin;
void* end;
void* capacity;
}
struct std_tree_node_base{
std_tree_node_base* left;
std_tree_node_base* parent;
std_tree_node_base* right;
char color;
char isNil;
short pad1;
//here will be the payload of the node, padded if needed
}
//red-black tree used to implement std::map, std::set
struct std_tree{
std_tree_node_base* head;
__int64 size;
}
struct std_list_node{
std_list_node* next;
std_list_node* prev;
//node payload here
}
struct std_list{
std_list_node* head;
__int64 size;
}
//same for std::wstring but using wchar_t*
struct std_string {
char* _Begin;
char* _End;
__int64 _MySize;
__int64 _MyReserved;
}
And maybe switch to IDA as its has a lot better decompiler than Ghidra. I think you can get the freeware version on their website, should suffice.
Good Luck!
Correct answer by Balan Narcis on September 27, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP