【发布时间】:2020-03-30 15:14:47
【问题描述】:
为了了解一些背景知识,我正在玩弄反调试技术。为了防止软件断点,可以在运行时搜索内存段内的 0xCC。此处的代码示例 -> https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/SoftwareBreakpoints.cpp
我想在运行时测试整个.text 部分并计算该部分的哈希值,而不是只检查一个函数。经过一番研究,我最终得到了类似的东西。
int main(int argc, TCHAR* argv[])
{
HMODULE imageBase = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)imageBase;
PIMAGE_NT_HEADERS imageHeader = (PIMAGE_NT_HEADERS)((SIZE_T)imageBase + imageDosHeader->e_lfanew);
SIZE_T base = (SIZE_T)imageBase + (SIZE_T)imageHeader->OptionalHeader.BaseOfCode;
SIZE_T end = (SIZE_T)base (SIZE_T)imageHeader->OptionalHeader.SizeOfCode;
int i = 0;
int total = 0;
while (base < end)
{
if (*((unsigned char*)base) != 0)
{
printf("ASM HEX: 0x%x \n", *((unsigned char*)base));
total += *((unsigned char*)base);
}
base++;
i++;
}
printf("i=%d\nTotal: %d\n", i, total);
return 0;
}
代码基本上是添加每条指令并打印总数(也打印所有指令,但为了清楚起见我将其删除)。只有一个.text/code 部分。
PS C:\Users\buildman\Source\Repos\Test\Debug> For ($i=1; $i -lt 10; $i++) {.\Test.exe | findstr "Total"}
总计:124027
总计:141202
总计:123952
总计:141502
总计:125677
总计:125677
总计:122602
总计:140302
总计:140302
问题是为什么每次的总数都不一样? 从一个编译到另一个我理解,但是我连续运行了 10 次相同的代码并且一些指令是不同的......这些添加的指令是什么,为什么?
在 Windows 7 中运行,但为 v110_XP 编译。在虚拟机内部。
谢谢。
编辑1:也许是因为ASLR,但它不应该是随机的吗?如果地址是随机的,总和总是不同的。
【问题讨论】:
-
快速浏览一下您的问题,如果您在运行时对
.text部分进行某种校验和,您的结果可能会受到需要运行时修复(重定位)的绝对地址的 ASLR 的影响)。数据或机器代码中具有绝对地址的任何地方都必须由 ASLR 修改。 (没有发布作为答案,因为我几乎没有仔细查看您的代码和 IDK 您是如何编译的。如果您的代码完全与位置无关,那么您不会看到 ASLR 的任何变化) -
另请注意,您不能只搜索
0xcc并假设这是int3。 -
它与位置无关。是的,ASLR 已激活,但位置取自标头。 @Jester 是的,是的,我知道 xD 这只是一个简化。我的哑数是某种校验和。
-
@Jester 这就是使校验和成为更好主意的原因。
-
我认为你误解了@PeterCordes 关于 ASLR 的评论。如果它处于活动状态,则代码本身需要在加载时进行修复,这将改变任何嵌入了地址的指令的内容。