【发布时间】:2019-11-01 11:47:15
【问题描述】:
编辑/更新
所以我认为让我感到困惑的是:
LEA ESI, [EBX + 8*EAX + 4]
加载一个地址,但是:
LEA ESI, [EBX + 4]
加载内容(值?)而不是地址。这怎么不取消引用?
我也不确定是什么
mov [eax+1], ecx
有吗?
原始问题
我正在努力学习阅读汇编,但是我开始挣扎。抱歉,如果有错别字,我无法从我的实验室机器上复制。这是来自恶意代码,因此可能不是最佳的。
我认为我在某个地方的理解有缺陷,但我就是想不通。
var_30 = byte ptr -30h
lea eax, [ebp+esi+var_30]
我的理解是加载有效地址将成为从 [basepointer-30h+esi] 计算的任何地址。我不知道 esi 或 edi 是什么。
lea ecx, [esi+edi]
lea ebx, [esi+6]
所以我相信ebx是esi + 6字节的结果地址?
mov esi, ds:WriteProcessMemory
esi 指向 WriteProcessMemory API 调用
mov byte ptr [eax], 68h
我认为将指令 PUSH 放入 eax 的地址(目前是 [basepointer-30h+esi]
mov [eax+1], ecx
我相信 ecx,现在是 [esi+edi] 的地址,包含要提供给 PUSH 指令的参数。这是否意味着 eax+1 现在指向内容 ecx([esi+edi] 中的内容)?
mov byte ptr [eax+5], 0C3h
我认为这会将指令 RET 放入地址 [eax+5]。
lea eax, [epb+var_30]
这实际上将 eax 向后/向前移动了 esi,但我不知道为什么?
push [ebp+lpBaseAddress]; lpBaseAddress
push 0FFFFFFFFh; hProcess (-1 = this process)
call esi
什么让我困惑:
ebx用作nSize的参数,但是为什么内容的长度会存储在地址[esi+6]?我最初认为它是 +6,因为这可能是 'PUSH arg RET (eax to eax+5)' 的长度,但它是一个地址而不是一个短整数。 short int (nSize) 是否被前一个子程序放置在该地址?
为什么 eax (lpBuffer - 要写入的内容) 现在位于 [eax-30h]。 esi 是否分配了空间,但从头开始写入内容?比如:
ebp+var_30+esi (eax, start of buffer address) : PUSH(eax) : arg(eax+1) RET(eax+5) : ebp+var_30 (new eax, end of buffer address)?
我不认为我完全理解 esi 或 edi 在做什么,但我没有完整的代码来确定它们是什么。
谢谢
【问题讨论】:
-
我认为从更简单的程序而不是恶意软件开始学习汇编语言会更容易。众所周知,恶意软件很难理解。
-
@nissimabehcera 从
WriteProcessMemory、lpBaseAddress、hProcess和 windows 标签来看,这看起来像 windows 代码。它也是32位的。您声称 “edi 寄存器存储函数的第一个参数和 esi 函数的第二个参数” 适用于 64 位 sysv 调用约定,而不是 32 位窗口。 -
lea ebx, [esi+6] 加载 esi+6 指向的 CONTENT 的有效地址。例如,如果 esi 寄存器的值为 0xffff1234,则 [esi+6] 是存储在地址 0xffff1234 的值加上 6 个字节。它类似于 C 语言中的指针,例如 (*ptr+6) => *ptr 访问 ptr 指向的值并添加 6 。 [epb+var_30] = [ebp-30h] ebp(基指针寄存器)指向栈的开头,栈向下增长。因此,如果您将数据压入堆栈,则指针需要“减少”压入数据的大小。
-
例如 ebp=0xffff3698 ,我需要在堆栈上存储一个值 10 然后一个值 20 => mov [ebp],10 mov [ebp-4] ,20 (因为堆栈是 4 个字节对齐的)。 “但是从头开始写内容”?是的,例如,你有“abc”要推入堆栈,如果 cpu 在字符串的开头插入,堆栈的内容看起来像 cba 但从结尾开始,abc
-
完整的代码,包括对
WriteProcessMemory的调用,将有助于更好地理解发生了什么。
标签: windows assembly x86 reverse-engineering