汇编如何在没有 ZF 标志访问的情况下将 JNE 转换为 C 代码

发布于 2024-12-09 15:37:10 字数 2146 浏览 0 评论 0原文

ASM 到 C 代码的模拟即将完成..只是试图解决这些第二遍问题。

假设我得到了这个 ASM 函数,

401040  MOV EAX,DWORD PTR [ESP+8]
401044  MOV EDX,DWORD PTR [ESP+4]
401048  PUSH ESI
401049  MOV ESI,ECX
40104B  MOV ECX,EAX
40104D  DEC EAX
40104E  TEST ECX,ECX
401050  JE 401083
401052  PUSH EBX
401053  PUSH EDI
401054  LEA EDI,[EAX+1]
401057  MOV AX,WORD PTR [ESI]
40105A  XOR EBX,EBX
40105C  MOV BL,BYTE PTR [EDX]
40105E  MOV ECX,EAX
401060  AND ECX,FFFF
401066  SHR ECX,8
401069  XOR ECX,EBX
40106B  XOR EBX,EBX
40106D  MOV BH,AL
40106F  MOV AX,WORD PTR [ECX*2+45F81C]
401077  XOR AX,BX
40107A  INC EDX
40107B  DEC EDI
40107C  MOV WORD PTR [ESI],AX
40107F  JNE 401057
401081  POP EDI
401082  POP EBX
401083  POP ESI
401084  RET 8

我的程序将为其创建以下内容。

int Func_401040() {
    regs.d.eax = *(unsigned int *)(regs.d.esp+0x00000008);
    regs.d.edx = *(unsigned int *)(regs.d.esp+0x00000004);
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.esi;
    regs.d.esi = regs.d.ecx;
    regs.d.ecx = regs.d.eax;
    regs.d.eax--;
    if(regs.d.ecx == 0)
        goto label_401083;
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.ebx;
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.edi;
    regs.d.edi = (regs.d.eax+0x00000001);
    regs.x.ax = *(unsigned short *)(regs.d.esi);
    regs.d.ebx ^= regs.d.ebx;
    regs.h.bl = *(unsigned char *)(regs.d.edx);
    regs.d.ecx = regs.d.eax;
    regs.d.ecx &= 0x0000FFFF;
    regs.d.ecx >>= 0x00000008;
    regs.d.ecx ^= regs.d.ebx;
    regs.d.ebx ^= regs.d.ebx;
    regs.h.bh = regs.h.al;
    regs.x.ax = *(unsigned short *)(regs.d.ecx*0x00000002+0x0045F81C);
    regs.x.ax ^= regs.x.bx;
    regs.d.edx++;
    regs.d.edi--;
    *(unsigned short *)(regs.d.esi) = regs.x.ax;
    JNE 401057
    regs.d.edi = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    regs.d.ebx = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    label_401083:
    regs.d.esi = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    return 0x8;
}

由于 JNE 401057 不使用 CMPTEST

我如何修复在 C 代码中使用它?

ASM to C Code emulating nearly done.. just trying to solve these second pass problems.

Lets say I got this ASM function

401040  MOV EAX,DWORD PTR [ESP+8]
401044  MOV EDX,DWORD PTR [ESP+4]
401048  PUSH ESI
401049  MOV ESI,ECX
40104B  MOV ECX,EAX
40104D  DEC EAX
40104E  TEST ECX,ECX
401050  JE 401083
401052  PUSH EBX
401053  PUSH EDI
401054  LEA EDI,[EAX+1]
401057  MOV AX,WORD PTR [ESI]
40105A  XOR EBX,EBX
40105C  MOV BL,BYTE PTR [EDX]
40105E  MOV ECX,EAX
401060  AND ECX,FFFF
401066  SHR ECX,8
401069  XOR ECX,EBX
40106B  XOR EBX,EBX
40106D  MOV BH,AL
40106F  MOV AX,WORD PTR [ECX*2+45F81C]
401077  XOR AX,BX
40107A  INC EDX
40107B  DEC EDI
40107C  MOV WORD PTR [ESI],AX
40107F  JNE 401057
401081  POP EDI
401082  POP EBX
401083  POP ESI
401084  RET 8

My program would create the following for it.

int Func_401040() {
    regs.d.eax = *(unsigned int *)(regs.d.esp+0x00000008);
    regs.d.edx = *(unsigned int *)(regs.d.esp+0x00000004);
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.esi;
    regs.d.esi = regs.d.ecx;
    regs.d.ecx = regs.d.eax;
    regs.d.eax--;
    if(regs.d.ecx == 0)
        goto label_401083;
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.ebx;
    regs.d.esp -= 4;
    *(unsigned int *)(regs.d.esp) = regs.d.edi;
    regs.d.edi = (regs.d.eax+0x00000001);
    regs.x.ax = *(unsigned short *)(regs.d.esi);
    regs.d.ebx ^= regs.d.ebx;
    regs.h.bl = *(unsigned char *)(regs.d.edx);
    regs.d.ecx = regs.d.eax;
    regs.d.ecx &= 0x0000FFFF;
    regs.d.ecx >>= 0x00000008;
    regs.d.ecx ^= regs.d.ebx;
    regs.d.ebx ^= regs.d.ebx;
    regs.h.bh = regs.h.al;
    regs.x.ax = *(unsigned short *)(regs.d.ecx*0x00000002+0x0045F81C);
    regs.x.ax ^= regs.x.bx;
    regs.d.edx++;
    regs.d.edi--;
    *(unsigned short *)(regs.d.esi) = regs.x.ax;
    JNE 401057
    regs.d.edi = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    regs.d.ebx = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    label_401083:
    regs.d.esi = *(unsigned int *)(regs.d.esp);
    regs.d.esp += 4;
    return 0x8;
}

Since JNE 401057 doesn't use the CMP or TEST

How do I fix that use this in C code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

末が日狂欢 2024-12-16 15:37:10

最近修改标志的指令是 dec,它在操作数达到 0 时设置 ZF。因此,jne 大约相当于 if (regs.d. edi!= 0)转到label_401057;。

顺便说一句:ret 8 不等于return 8ret 指令的操作数是返回时添加到 ESP 的字节数。 (它通常用于清理堆栈。)这有点像

return eax;
regs.d.esp += 8;

,只是半明显地,这在 C 中不起作用——return 使得它后面的任何代码都无法访问。

这实际上是调用约定的一部分 - [ESP+4][ESP+8] 是传递给函数的参数,而 ret< /code> 正在清理它们。这不是通常的 C 调用约定;考虑到该函数需要 ECX 中的值,它看起来更像是 fastcall 或 thiscall。

The most recent instruction that modified flags is the dec, which sets ZF when its operand hits 0. So the jne is about equivalent to if (regs.d.edi != 0) goto label_401057;.

BTW: ret 8 isn't equivalent to return 8. The ret instruction's operand is the number of bytes to add to ESP when returning. (It's commonly used to clean up the stack.) It'd be kinda like

return eax;
regs.d.esp += 8;

except that semi-obviously, this won't work in C -- the return makes any code after it unreachable.

This is actually a part of the calling convention -- [ESP+4] and [ESP+8] are arguments passed to the function, and the ret is cleaning those up. This isn't the usual C calling convention; it looks more like fastcall or thiscall, considering the function expects a value in ECX.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文