2012-12-02 64 views
3

我在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讓我一個很好的控制結構,以及: enter image description here

正如你所看到的代碼是這樣的:

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」 已經是在樹上,不是嗎?

回答

2

快速瀏覽一下,這似乎是一個二叉樹,用於計算字符串出現次數。樹節點的樣子:

const char* text; 
int count; 
node* left; 
node* right; 

函數本身int addstring(node** root, const char* text) 首先代碼檢查,如果樹是空的,並跳過搜索,如果它是。 搜索從0x10開始,做if (strcmp(current->text, text) > 0) current = current->right;並循環回來。這段代碼看起來並沒有優化,在0x4E處它做了相同的比較,這次檢查了< 0並向左走。在0x9B處是「找到」分支,它遞增計數器並返回1.

如果未找到文本,則會在0x85處創建一個新節點,插入樹中,並使用strdup將文本複製到其中如malloc(strlen()) + strcpy)。新節點的兩個leftright被設置爲NULLcount爲1

更新:節點大小是16個字節如可以從malloc調用中可以看出。偏移量0用於比較文本,因此必須是文本。偏移量4遞增,所以必須是計數器。偏移量8和12是兩個子指針,因爲它們是這樣使用的。

IDA所提出的原型是無稽之談,第一個參數必須是一個指針,否則它將炸燬。此外,C區分大小寫,因此請嘗試FB3(首都)。 事情是這樣的:

#include <stdio.h> 
extern int FB3(void** root, const char *text); 

int main(void) 
{ 
    void* root = NULL; 
    int i = FB3(&root, "e3y"); 
    printf("%p %d", root, i); 

    return 0; 
} 

如果這樣的作品,你可以繼續添加節點結構,以便您可以然後遍歷和C.打印樹

+0

我加了一些改變上述問題,檢查它請。謝謝。 – amman

+0

不錯,它現在建立。 你確定,它必須是節點**? 因爲它現在正在爲我工​​作(未處理的exeption)。 我更新了我的帖子,你可以看到結果。 – amman

+0

是的,它必須是'node **'。它只是意外地爲你工作,因爲你分配了一個節點(你不應該這樣做)並且將'count'設置爲0.然後'FB3'將使用'count'作爲根節點。你應該能夠看到,如果你打印'root-> count'。 另外,返回值不是'count'。這只是內存分配的成功(1)/失敗(0)指示。 – Jester