我目前正在尝试绕过CRC检查,该检查在应用程序的许多地方都内联,以检查.text节中的内存页是否已被修改。

crc32指令的简短说明:

从第一个操作数(目标操作数)中的初始值开始,为第二个操作数(源操作数)累积CRC32(多项式11EDC6F41H)值,并将结果存储在目标操作数中。

好吧:rsi包含要扫描的下一个内存页面的指针,而rax是偏移量/计数器。 rdx通常为200(200个循环)。
我的目标:找到设置rsi的位置。必须有一些指令,例如mov rsi, next_memory_page_to_be_scanned
代码中的进一步内容:

所以这是初始化的循环变量(rdx,rax)。 />所以这是我遇到的问题之一:黄色标记部分似乎是我可以在CRC_CHECK之前执行的第一条指令。我的意思是显然还有其他地方叫它,但我不知道如何找到那个地方。上面的一条指令断点(and [rcx], al)不会触发bp(似乎与CRC检查无关)。我如何进一步回溯呢?
当我对CRC进行bp校验时,rsi的值也不位于堆栈中。
谢谢!

评论

清单中的两个电话怎么样?还是此函数的调用方?

这两个调用都不会被调用,函数本身也不会被调用,至少当我在开始时不调用该函数时(至少对于CRC计算而言)。在这里执行的第一条指令/您可以bp的指令是movsd qword ...(黄色标记部分)

您能告诉我们操作码和地址的字节吗?这个和其他[rdx + r14 * 8-7BFAEFF1h]看起来很奇怪,我怀疑IDA可能无法识别并向您显示错误的反汇编时发生了一些混淆。

i.imgur.com/wGE8XX5.png这是此函数的字节

您确定要调查的代码不是由于某些反调试而被引导的陷阱吗?也许您可以使用硬写的INT3修改文件,然后查看代码是否在没有调试器的情况下到达那里。如果是,您可以在此时附加Ida并查看它是否与调试时相同。

#1 楼

跳过Igor关于跟踪的建议,您是否尝试过通过作弊引擎进行中断和跟踪?如果不是,请考虑以下因素:


是否通过字节数组(首先需要AOB扫描;请确保选择读/写存储器),模块+偏移量或符号名称(如果适用) ),在Cheat Engine的反汇编程序(内存查看器的上半部分)中找到前往crc32 edi, qword ptr [rsi+rax*8]指令的方式。
右键单击该指令,然后选择Break and trace instructions。 ,然后单击Save stack snapshots
在Tracer窗口中填充了跟踪信息后,右键单击它,然后选择Step over instead of single step
滚动到树的最远分支,其中最上面的指令应为OK指令。
单击Expand all按钮并保持打开的窗口(堆栈视图)在Tracer窗口旁边。通过呼叫者与每个分支进行备份)。您可以通过堆栈视图窗口查看右侧的寄存器以及堆栈。您可以双击“跟踪器”中的任何指令以转到反汇编器中的该指令,然后可以在其中通过调用程序的子例程进行读取。

如果没有足够的分支您,然后再次运行跟踪,并将跟踪的初始指令数从1000更改为所需的任何值。另外,如果您发现进入呼叫者子程序的方式,并且想从中钻取其他呼叫,只需在呼叫之前的某个时刻运行另一个中断/跟踪,然后不要选择(或最后,作为另一个提示,在Memory Viewer中,如果您运行crc32 edi, qword ptr [rsi+rax*8],则可以选择基本模块和任何其他依赖项来运行一堆自动执行任务,例如查找所有引用的字符串和函数,以及查找所有例程的所有外部参照!外部参照非常适合能够转到任何给定功能的序言(右键单击任何指令并选择Stack,然后滚动到顶部)并快速查看有多少调用者(您可以双击其中的者)

这可以让您快速查看功能是否共享,从而有可能充当Step over instead of single step修补程序的枢轴点(或者,您更愿意修补程序),或允许您选择要单独修补的特定功能的特定呼叫说明。

#2 楼

听起来程序正在使用某种混淆处理。您可能应该从头开始逐步执​​行或记录一条指令跟踪记录,以了解最终如何执行这些指令。