如何将 HASH 字节放入 OllyDbg 的内存地址
How to put a HASH bytes in a memory address with OllyDbg
我正在使用 OllyDbg 修改应用程序,但我对汇编语言很陌生,我需要在内存地址中放置一个 MD5 散列,目标内存地址存储在 EAX
.我该怎么做?
我需要插入的散列是dba2d8bf7063faf1275e693661bc9651
。我尝试过以下方式:
MOV DWORD PTR DS:[EAX],32616264
MOV DWORD PTR DS:[EAX+4],66623864
MOV DWORD PTR DS:[EAX+8],33363037
MOV DWORD PTR DS:[EAX+12],31666166
MOV DWORD PTR DS:[EAX+16],65353732
MOV DWORD PTR DS:[EAX+20],36333936
MOV DWORD PTR DS:[EAX+24],63623136
MOV DWORD PTR DS:[EAX+28],31353639
但我认为它很长而且效率很低。我也尝试过将散列保存在另一个地址并使用 MOV
指令将其移动到我需要的位置,但我无法使其工作:
MOV DWORD PTR DS:[EAX], 012B2C60
其中012B2C60
是哈希地址。
我遇到的另一个问题是,黄色下划线的字节在我启动程序的时候被修改了(我猜应该是动态地址)所以我在那个地址写的东西在程序启动的时候被修改了,我怎么能防止这种情况发生?
BTW,为什么要复制32个字节? MD5 hashes are 16 bytes。您是否正在复制它的 ASCII 表示形式?
MOV DWORD PTR DS:[EAX], 012B2C60
你不能在不修改寄存器的情况下将内存复制到内存。此外,具有 32 位绝对地址的 8 个 dword
mov 指令序列即使是可编码的也不会更短,因为每个指令都需要 012B2C60
地址。
如果您可以破坏 XMM 或 YMM 寄存器(或 save/restore 它在堆栈上),则可以使用 2 个 XMM SSE load/store 对或单个 AVX vmovdqu ymm4, [012B2C60]
/ vmovdqu [eax], ymm4
如果执行此操作后程序的性能很重要,如果周围的代码已经在使用 AVX,请使用 AVX。否则将 SSE movups
与 XMM 寄存器一起使用。 ().
您可以通过 推送 esi、edi 和 ecx 并使用 ecx=8
/ rep movsd
来实现 memcpy,然后恢复 regs,而不是 AVX 或 SSE ]. (对于 edi,您可以在 rep movsd 之前 xchg eax, edi
,然后 sub edi, 32
,然后再次 xchg
。对于性能 IDK,如果这比 push/pop 到 save/restore 更好不过和其他人一起。
或者,如果您不必保存寄存器,rep movsd
对于代码大小来说非常适合 运行-once 效率。
如果您的代码在程序启动时只执行一次 运行s,那么除非代码大小是一个真正的问题,否则使用即时数据而不是复制可能是最简单的方法。这对总体 space 效率不是很好,因为数据的每个双字需要 3 个额外字节:操作码、modrm 和 disp8(第一个使用裸 [eax]
寻址模式的除外。push
具有更好的即时数据密度,但只能压入堆栈。
64 位模式的帮助很小; mov r64, imm64
是 10 个字节,但仅适用于寄存器目标。
- 将您的哈希码存储在代码段的底部。通常你可以在代码段中看到许多从不改变的空闲字节。他们是零。数据段用于您的全局变量,因此它们可能会更改,但代码段字节永远不会更改。
- 使用
memcpy
函数将这些字节复制到您的目标内存地址。
我正在使用 OllyDbg 修改应用程序,但我对汇编语言很陌生,我需要在内存地址中放置一个 MD5 散列,目标内存地址存储在 EAX
.我该怎么做?
我需要插入的散列是dba2d8bf7063faf1275e693661bc9651
。我尝试过以下方式:
MOV DWORD PTR DS:[EAX],32616264
MOV DWORD PTR DS:[EAX+4],66623864
MOV DWORD PTR DS:[EAX+8],33363037
MOV DWORD PTR DS:[EAX+12],31666166
MOV DWORD PTR DS:[EAX+16],65353732
MOV DWORD PTR DS:[EAX+20],36333936
MOV DWORD PTR DS:[EAX+24],63623136
MOV DWORD PTR DS:[EAX+28],31353639
但我认为它很长而且效率很低。我也尝试过将散列保存在另一个地址并使用 MOV
指令将其移动到我需要的位置,但我无法使其工作:
MOV DWORD PTR DS:[EAX], 012B2C60
其中012B2C60
是哈希地址。
我遇到的另一个问题是,黄色下划线的字节在我启动程序的时候被修改了(我猜应该是动态地址)所以我在那个地址写的东西在程序启动的时候被修改了,我怎么能防止这种情况发生?
BTW,为什么要复制32个字节? MD5 hashes are 16 bytes。您是否正在复制它的 ASCII 表示形式?
MOV DWORD PTR DS:[EAX], 012B2C60
你不能在不修改寄存器的情况下将内存复制到内存。此外,具有 32 位绝对地址的 8 个 dword
mov 指令序列即使是可编码的也不会更短,因为每个指令都需要 012B2C60
地址。
如果您可以破坏 XMM 或 YMM 寄存器(或 save/restore 它在堆栈上),则可以使用 2 个 XMM SSE load/store 对或单个 AVX vmovdqu ymm4, [012B2C60]
/ vmovdqu [eax], ymm4
如果执行此操作后程序的性能很重要,如果周围的代码已经在使用 AVX,请使用 AVX。否则将 SSE movups
与 XMM 寄存器一起使用。 (
您可以通过 推送 esi、edi 和 ecx 并使用 ecx=8
/ rep movsd
来实现 memcpy,然后恢复 regs,而不是 AVX 或 SSE ]. (对于 edi,您可以在 rep movsd 之前 xchg eax, edi
,然后 sub edi, 32
,然后再次 xchg
。对于性能 IDK,如果这比 push/pop 到 save/restore 更好不过和其他人一起。
或者,如果您不必保存寄存器,rep movsd
对于代码大小来说非常适合 运行-once 效率。
如果您的代码在程序启动时只执行一次 运行s,那么除非代码大小是一个真正的问题,否则使用即时数据而不是复制可能是最简单的方法。这对总体 space 效率不是很好,因为数据的每个双字需要 3 个额外字节:操作码、modrm 和 disp8(第一个使用裸 [eax]
寻址模式的除外。push
具有更好的即时数据密度,但只能压入堆栈。
64 位模式的帮助很小; mov r64, imm64
是 10 个字节,但仅适用于寄存器目标。
- 将您的哈希码存储在代码段的底部。通常你可以在代码段中看到许多从不改变的空闲字节。他们是零。数据段用于您的全局变量,因此它们可能会更改,但代码段字节永远不会更改。
- 使用
memcpy
函数将这些字节复制到您的目标内存地址。