asm source code note 1.8_没有原文的asm to c

来源:互联网 发布:淘宝微博小号店铺推荐 编辑:程序博客网 时间:2024/04/25 22:14

//asm source code note 1.8_没有原文的asm to c

//<<天书夜读>> section 2, page 21, asm code

00411a20 push ebp
00411a21 mov ebp, esp
00411a23 sub esp, 0e8h
00411a29 push ebx
00411a2a push esi
00411a2b push edi
00411a2c lea edi, [ebp-0e8h]
00411a32 mov ecx, 3ah
00411a37 mov eax, 0cccccccch
00411a3c rep stos dword ptr [edi]
00411a3e mov eax, dword ptr [a]
00411a41 add eax, dword ptr [b]
00411a44 mov dowrd ptr [d], eax
00411a47 mov dword ptr [i], 1
00411a4e mov dowrd ptr [c], 0
00411a55 cmp dowrd ptr [c], 64h
00411a59 jge myfunction +46h (411a66h)
00411a5b mov eax, dword ptr [c]
00411a5e add eax, dowrd ptr [i]
00411a61 mov dword ptr [c], eax
00411a64 jmp myfunction + 35h (411a55h)
00411a66 mov eax, dowrd ptr [c]
00411a69 mov dword ptr[ebp-0e8h], eax
00411a6f cmp dword ptr[ebp-0e8h], 0
00411a76 je myfunction+63h (411a83h)
00411a78 cmp dword ptr[ebp-0e8h], 1
00411a7f je myfunction + 6ah (411a8ah)
00411a81 jmp myfunction+72h (411a92h)
00411a83 mov dowrd ptr[d], 1
00411a8a mov eax, dowrd ptr[c]
00411a8d mov dowrd ptr[d], eax
00411a90 jmp myfunction+79h (411a99h)
00411a92 mov dword ptr[d], 0
00411a99 mov eax, dowrd ptr[d]
00411a9c pop edi
00411a9d pop esi
00411a9e pop ebx
00411a9f mov esp, ebp
00411aa1 pop ebp
00411aa2 ret

// asm to c
// 保存现场
    00411a20 push ebp
    00411a21 mov ebp, esp
    00411a23 sub esp, 0e8h
    00411a29 push ebx
    00411a2a push esi
    00411a2b push edi
// 初始化内部变量区
    00411a2c lea edi, [ebp-0e8h]
    00411a32 mov ecx, 3ah
    00411a37 mov eax, 0cccccccch
    00411a3c rep stos dword ptr [edi]

#define var1 [ebp-0e8h]

// d = a + b;
    00411a3e mov eax, dword ptr [a]
    00411a41 add eax, dword ptr [b]
    00411a44 mov dowrd ptr [d], eax
// i = 1;
// c = 0;
    00411a47 mov dword ptr [i], 1
    00411a4e mov dowrd ptr [c], 0
jmp_pt2:
//if(c >= 0x64)
// goto jmp_pt1;
    00411a55 cmp dowrd ptr [c], 64h
    00411a59 jge myfunction +46h (411a66h)// => jmp_pt1:
// c = c + i;
    00411a5b mov eax, dword ptr [c]
    00411a5e add eax, dowrd ptr [i]
    00411a61 mov dword ptr [c], eax
// goto jmp_pt2;
    00411a64 jmp myfunction + 35h (411a55h)// => jmp_pt2:
jmp_pt1:
// var1 = c;
// if(var1 == 0)
//    goto jmp_pt3;
    00411a66 mov eax, dowrd ptr [c]
    00411a69 mov dword ptr[ebp-0e8h], eax
    00411a6f cmp dword ptr[ebp-0e8h], 0
    00411a76 je myfunction+63h (411a83h)// => jmp_pt3:
// if(var1 == 1)
//    goto jmp_pt4;
//    goto jmp_pt5;
    00411a78 cmp dword ptr[ebp-0e8h], 1
    00411a7f je myfunction + 6ah (411a8ah)// => jmp_pt4:
    00411a81 jmp myfunction+72h (411a92h)// => jmp_pt5:
jmp_pt3:
// d = 1;
    00411a83 mov dowrd ptr[d], 1
jmp_pt4:
// d = c;
// goto jmp_pt6;
    00411a8a mov eax, dowrd ptr[c]
    00411a8d mov dowrd ptr[d], eax
    00411a90 jmp myfunction+79h (411a99h)// => jmp_pt6:
jmp_pt5:
// d = 0;
    00411a92 mov dword ptr[d], 0
jmp_pt6:
// return d;
    00411a99 mov eax, dowrd ptr[d]

//恢复现场并返回
    00411a9c pop edi
    00411a9d pop esi
    00411a9e pop ebx
    00411a9f mov esp, ebp
    00411aa1 pop ebp
    00411aa2 ret

//伪代码整理
DWORD fn()
{
    DWORD var1;

    d = a + b;
    i = 1;
    c = 0;

jmp_pt2:
    if(c >= 0x64)
        goto jmp_pt1;
    c = c + i;
    goto jmp_pt2;
jmp_pt1:
    var1 = c;
    if(var1 == 0)
        goto jmp_pt3;
    if(var1 == 1)
        goto jmp_pt4;
        goto jmp_pt5;
jmp_pt3:
    d = 1;
jmp_pt4:
    d = c;
    goto jmp_pt6;
jmp_pt5:
    d = 0;
jmp_pt6:
    return d;
}

//pseudocode to c
DWORD fn(a, b, c, d, i)
{
    d = a + b;
    i = 1;
    c = 0;

    while(c < 0x64)
    {
        c = c + i;
    }

    switch(c)
    {
    case 0:
        d = 1;
    case 1:
        d = c;
        break;
    default:
        d = 0;
        break;
    }

    return d;
}

//note
asm to c时,
1. 缩进asm代码
2. 整理出跳转的标号, 在有掉转的asm代码后面把标砖标号标注上
3. 把保存现场和恢复现场的代码先隔离开, 中间的asm代码是要翻译的
4. 翻译后的代码写在(标号的下面, 汇编代码的前面), 避免看错
5. 声明内部变量[ebp - xx], 便于翻译
6. 翻译出asm代码
7. 去掉asm代码,留下标号, 内部变量声明和翻译后的伪代码
    asm代码在开始翻译前,已经做了缩进, 很容易看清
8. 去掉翻译时留下的注释符号//
9. 把声明的内部变量定义成变量
10. 整理伪代码的书写风格
11. 把伪代码整理成c代码, 按照循环和分支的c实现, 把标号和goto换掉
12. 优化c代码, 把编译器用到的内部变量尽量用形参代替

逆向后的c函数fn(a, b, c, d, i)没有一点逻辑性, 是些无法理解的代码,
看不出这个函数是干啥的, 不过确实是这样的, 翻译的并没有错

可能是此段asm代码是用于练习用的, 而且这段asm源码和实际asm并不相同.

例如: 00411a66 mov eax, dowrd ptr [c], 在实际的asm代码中c应该是地址,
这个地址不是内部变量[ebp-xx], 就是形参[ebp+xx],
应该写成
00411a66 mov eax, dowrd ptr [ebp-xx]或
00411a66 mov eax, dowrd ptr [ebp+xx]