运行时使用相同的二进制但不同的汇编指令-Windows 7

运行时使用相同的二进制但不同的汇编指令-Windows 7,windows,assembly,binary,Windows,Assembly,Binary,有一点背景知识,我是在玩弄反调试技术。为了防止软件断点,可以在运行时在内存段内搜索0xCC。这里的代码示例-> 我不想只检查一个函数,而是想在运行时测试整个.text部分,并计算该部分的哈希值。经过一些研究,我最终得到了这样的结果 int main(int argc,TCHAR*argv[]) { HMODULE imageBase=GetModuleHandle(NULL); PIMAGE\U DOS\U HEADER IMAGEDOSSHEADER=(PIMAGE\U DOS\U HEAD

有一点背景知识,我是在玩弄反调试技术。为了防止软件断点,可以在运行时在内存段内搜索0xCC。这里的代码示例->

我不想只检查一个函数,而是想在运行时测试整个
.text
部分,并计算该部分的哈希值。经过一些研究,我最终得到了这样的结果


int main(int argc,TCHAR*argv[])
{
HMODULE imageBase=GetModuleHandle(NULL);
PIMAGE\U DOS\U HEADER IMAGEDOSSHEADER=(PIMAGE\U DOS\U HEADER)imageBase;
PIMAGE\u NT\u HEADERS imageheaders=(PIMAGE\u NT\u HEADERS)((SIZE\u T)imageBase+imageDosHeader->e\u lfanew);
SIZE\u T base=(SIZE\u T)imageBase+(SIZE\u T)imageHeader->OptionalHeader.BaseOfCode;
SIZE\u T end=(SIZE\u T)base(SIZE\u T)imageHeader->OptionalHeader.SizeOfCode;
int i=0;
int-total=0;
while(基<端)
{
如果(*(无符号字符*)基)!=0)
{
printf(“ASM十六进制:0x%x\n”,*((无符号字符*)基));
总计+=*((无符号字符*)基数);
}
base++;
i++;
}
printf(“i=%d\n总计:%d\n”,i,总计);
返回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次运行相同的代码,而且有些指令是不同的。。。这些附加说明是什么?为什么

在Windows7中运行它,但为v110\uXP编译。在虚拟机内部

多谢各位


编辑1:可能是因为ASLR,但它不应该是随机的吗?如果地址是随机的,那么总和总是不同的。

@PeterCordes是对的(请查看注释)。这是因为ASLR,我刚刚在ASLR关闭的情况下测试了代码,结果总是一样的。

@PeterCordes是对的(请查看注释)。这是因为ASLR,我刚刚在ASLR关闭的情况下测试了代码,结果总是一样的。

快速浏览一下您的问题,如果您在运行时对
.text
部分进行某种校验和,您的结果可能会受到绝对地址的ASLR的影响,这需要运行时修复(重新定位)。ASLR必须修改数据或机器代码中具有绝对地址的任何地方。(不是作为回答发帖,因为我几乎没看过你的代码和IDK,你是如何编译的。如果你的代码纯粹是位置独立的,你不会看到ASLR的任何变化)还要注意,你不能只搜索
0xcc
,然后假设那是
int3
。它是位置独立的。是,ASLR已激活,但位置取自收割台@杰斯特:是的,是的,我知道,这只是一种简化。我的哑和是某种校验和。@Jester这就是校验和更好的想法。我想你误解了@PeterCordes对ASLR的评论。如果它处于活动状态,则代码本身需要在加载时固定,这将更改任何嵌入地址的指令的内容。快速浏览您的问题,如果您在运行时对
.text
部分执行某种校验和,您的结果可能会受到需要运行时修复(重新定位)的绝对地址ASLR的影响。ASLR必须修改数据或机器代码中具有绝对地址的任何地方。(不是作为回答发帖,因为我几乎没看过你的代码和IDK,你是如何编译的。如果你的代码纯粹是位置独立的,你不会看到ASLR的任何变化)还要注意,你不能只搜索
0xcc
,然后假设那是
int3
。它是位置独立的。是,ASLR已激活,但位置取自收割台@杰斯特:是的,是的,我知道,这只是一种简化。我的哑和是某种校验和。@Jester这就是校验和更好的想法。我想你误解了@PeterCordes对ASLR的评论。如果它是活动的,那么代码本身将需要在加载时固定,这将改变任何嵌入地址的指令的内容。