我在uni有一門課程(逆向工程),我有作業。 我有一個.obj文件(它是用visual studio 2008編譯的),我必須反彙編它,找出控制結構並在一個小c程序中調用它。反彙編並使用.obj文件
我用IDA反編譯,這裏是彙編代碼:
_FB3:
00000000: 55 push ebp
00000001: 56 push esi
00000002: 57 push edi
00000003: 8B 7C 24 10 mov edi,dword ptr [esp+10h]
00000007: 83 3F 00 cmp dword ptr [edi],0
0000000A: 74 79 je 00000085
0000000C: 8D 64 24 00 lea esp,[esp]
00000010: 8B 2F mov ebp,dword ptr [edi]
00000012: 8B 75 00 mov esi,dword ptr [ebp]
00000015: 8B 44 24 14 mov eax,dword ptr [esp+14h]
00000019: 8B CE mov ecx,esi
0000001B: EB 03 jmp 00000020
0000001D: 8D 49 00 lea ecx,[ecx]
00000020: 8A 10 mov dl,byte ptr [eax]
00000022: 3A 11 cmp dl,byte ptr [ecx]
00000024: 75 1A jne 00000040
00000026: 84 D2 test dl,dl
00000028: 74 12 je 0000003C
0000002A: 8A 50 01 mov dl,byte ptr [eax+1]
0000002D: 3A 51 01 cmp dl,byte ptr [ecx+1]
00000030: 75 0E jne 00000040
00000032: 83 C0 02 add eax,2
00000035: 83 C1 02 add ecx,2
00000038: 84 D2 test dl,dl
0000003A: 75 E4 jne 00000020
0000003C: 33 C0 xor eax,eax
0000003E: EB 05 jmp 00000045
00000040: 1B C0 sbb eax,eax
00000042: 83 D8 FF sbb eax,0FFFFFFFFh
00000045: 85 C0 test eax,eax
00000047: 7D 05 jge 0000004E
00000049: 8D 7D 0C lea edi,[ebp+0Ch]
0000004C: EB 32 jmp 00000080
0000004E: 8B 44 24 14 mov eax,dword ptr [esp+14h]
00000052: 8B CE mov ecx,esi
00000054: 8A 10 mov dl,byte ptr [eax]
00000056: 3A 11 cmp dl,byte ptr [ecx]
00000058: 75 1A jne 00000074
0000005A: 84 D2 test dl,dl
0000005C: 74 12 je 00000070
0000005E: 8A 50 01 mov dl,byte ptr [eax+1]
00000061: 3A 51 01 cmp dl,byte ptr [ecx+1]
00000064: 75 0E jne 00000074
00000066: 83 C0 02 add eax,2
00000069: 83 C1 02 add ecx,2
0000006C: 84 D2 test dl,dl
0000006E: 75 E4 jne 00000054
00000070: 33 C0 xor eax,eax
00000072: EB 05 jmp 00000079
00000074: 1B C0 sbb eax,eax
00000076: 83 D8 FF sbb eax,0FFFFFFFFh
00000079: 85 C0 test eax,eax
0000007B: 7E 1E jle 0000009B
0000007D: 8D 7D 08 lea edi,[ebp+8]
00000080: 83 3F 00 cmp dword ptr [edi],0
00000083: 75 8B jne 00000010
00000085: 6A 10 push 10h
00000087: E8 00 00 00 00 call _malloc
0000008C: 83 C4 04 add esp,4
0000008F: 89 07 mov dword ptr [edi],eax
00000091: 85 C0 test eax,eax
00000093: 75 14 jne 000000A9
00000095: 5F pop edi
00000096: 5E pop esi
00000097: 33 C0 xor eax,eax
00000099: 5D pop ebp
0000009A: C3 ret
0000009B: 8B C5 mov eax,ebp
0000009D: FF 40 04 inc dword ptr [eax+4]
000000A0: 5F pop edi
000000A1: 5E pop esi
000000A2: B8 01 00 00 00 mov eax,1
000000A7: 5D pop ebp
000000A8: C3 ret
000000A9: 8B 74 24 14 mov esi,dword ptr [esp+14h]
000000AD: 8B C6 mov eax,esi
000000AF: 8D 50 01 lea edx,[eax+1]
000000B2: 8A 08 mov cl,byte ptr [eax]
000000B4: 40 inc eax
000000B5: 84 C9 test cl,cl
000000B7: 75 F9 jne 000000B2
000000B9: 2B C2 sub eax,edx
000000BB: 40 inc eax
000000BC: 50 push eax
000000BD: E8 00 00 00 00 call _malloc
000000C2: 8B 0F mov ecx,dword ptr [edi]
000000C4: 89 01 mov dword ptr [ecx],eax
000000C6: 8B 07 mov eax,dword ptr [edi]
000000C8: 83 C4 04 add esp,4
000000CB: 83 38 00 cmp dword ptr [eax],0
000000CE: 74 C5 je 00000095
000000D0: 8B 10 mov edx,dword ptr [eax]
000000D2: 8B CE mov ecx,esi
000000D4: 8A 01 mov al,byte ptr [ecx]
000000D6: 88 02 mov byte ptr [edx],al
000000D8: 41 inc ecx
000000D9: 42 inc edx
000000DA: 84 C0 test al,al
000000DC: 75 F6 jne 000000D4
000000DE: 8B 17 mov edx,dword ptr [edi]
000000E0: C7 42 04 01 00 00 mov dword ptr [edx+4],1
00
000000E7: 8B 07 mov eax,dword ptr [edi]
000000E9: C7 40 08 00 00 00 mov dword ptr [eax+8],0
00
000000F0: 8B 0F mov ecx,dword ptr [edi]
000000F2: 5F pop edi
000000F3: 5E pop esi
000000F4: C7 41 0C 00 00 00 mov dword ptr [ecx+0Ch],0
00
000000FB: B8 01 00 00 00 mov eax,1
00000100: 5D pop ebp
00000101: C3 ret
IDA讓我一個很好的控制結構,以及:
正如你所看到的代碼是這樣的:
for(...)
{
for1(...){...}
...
for1(...){...}
}
malloc
....
for3() ...
malloc
...
for2(...)
{
...
}
據我所知,for1和for2具有幾乎相同的結構,只有活動是不同的,而for3的實現函數在for1和for2函數族中。 for3使用第二個malloc的結果作爲參數,所以我認爲for2應該是某種數組複製循環。 for1,for2和for3是已知的stdc內聯實現。
有人可以幫助我如何找出這個F3函數的目的?
第二個問題:如何在一個小樣本C程序中使用這個.obj文件? 如何在VS中調用它的函數?
在此先感謝,任何幫助表示讚賞。
UPDATE: Jester:有趣。你怎麼知道節點的結構? 我仍然試圖弄清楚這件事(在你的幫助下),但還沒有。
我想通了,IDA反彙編器有一個僞代碼查看功能。 這裏是僞:
signed int __cdecl FB3(int a1, const char *a2)
{
int v2; // [email protected]
const char **v3; // [email protected]
void *v4; // [email protected]
signed int result; // [email protected]
int v6; // [email protected]
const char *v7; // [email protected]
const char v8; // [email protected]
v2 = a1;
while (*(_DWORD *)v2)
{
v3 = *(const char ***)v2;
if (strcmp(a2, **(const char ***)v2) >= 0)
{
if (strcmp(a2, **(const char ***)v2) <= 0)
{
++v3[1];
return 1;
}
v2 = (int)(v3 + 2);
}
else
{
v2 = (int)(v3 + 3);
}
}
v4 = malloc(0x10u);
*(_DWORD *)v2 = v4;
if (v4 && (**(_DWORD **)v2 = malloc(strlen(a2) + 1)) != 0)
{
v6 = **(_DWORD **)v2;
v7 = a2;
do
{
v8 = *v7;
*(_BYTE *)v6++ = *v7++;
}
while (v8);
*(_DWORD *)(*(_DWORD *)v2 + 4) = 1;
*(_DWORD *)(*(_DWORD *)v2 + 8) = 0;
*(_DWORD *)(*(_DWORD *)v2 + 12) = 0;
result = 1;
}
else
{
result = 0;
}
return result;
}
從這個也許是在一個字符串計數一批的occurence? 這個僞代碼對我來說有點朦朧。
我試圖在示例程序中調用此函數,但沒有成功。 我用過:extern signed int fb3(int a1,const char * a2); 然後我試圖調用它,但鏈接器給了我「在函數_main中引用的未解析的外部符號_fb3」錯誤(所以,我沒有在.bj文件中使用該extern關鍵字聲明的這個簽名的fb3函數。所以簽名是錯誤的)。
這裏是我試圖使用示例程序(main.c中):
#include <stdio.h>
extern signed int fb3(int a1, const char *a2);
int main(void)
{
char b[3] = {'e','3','y'};
signed int i = fb3(3,b);
printf("%d",i);
return 0;
}
我已經設置的連接體輸入(VS2010)至f3.obj爲好。
UPDATE2: 我實現了節點結構,並使用了區分大小寫的功能名稱,現在我可以編譯成功。
示例程序:
#include <stdio.h>
typedef struct node
{
int count;
const char * text;
struct node* right;
struct node* left;
} node;
extern int FB3(node* root, const char *text);
int main(void)
{
node* root;
signed int i;
int j;
root = (node*)malloc(sizeof(node));
root->count = 0;
root->text = "textone";
root->right = NULL;
root->left = NULL;
printf("value = %d\n", FB3(root,"v"));
printf("value = %d\n", FB3(root,"b"));
printf("value = %d\n", FB3(root,"c"));
printf("value = %d\n", FB3(root,"3dasf"));
printf("value = %d\n", FB3(root,"3ssdfs"));
printf("value = %d\n", FB3(root,"dsda"));
printf("value = %d\n", FB3(root,"v"));
printf("value = %d\n", FB3(root,"gsda"));
printf("value = %d\n", FB3(root,"gsda"));
printf("value = %d\n", FB3(root,"a"));
printf("value = %d\n", FB3(root,"ab"));
return 0;
}
輸出是:
value=1
value=1
value=1
... (only value=1)
有趣的是,7日的printf應該printf的 「值= 2」,因爲 「V」 已經是在樹上,不是嗎?
我加了一些改變上述問題,檢查它請。謝謝。 – amman
不錯,它現在建立。 你確定,它必須是節點**? 因爲它現在正在爲我工作(未處理的exeption)。 我更新了我的帖子,你可以看到結果。 – amman
是的,它必須是'node **'。它只是意外地爲你工作,因爲你分配了一個節點(你不應該這樣做)並且將'count'設置爲0.然後'FB3'將使用'count'作爲根節點。你應該能夠看到,如果你打印'root-> count'。 另外,返回值不是'count'。這只是內存分配的成功(1)/失敗(0)指示。 – Jester