如何使用C ++从.exe读取/写入asm寄存器?

时间:2015-09-05 23:42:20

标签: c++ assembly executable

我想修改某个程序中的寄存器的值。 唯一的问题是,我不知道如何访问它。如果有办法,我该如何读/写? (首选语言C ++)

2 个答案:

答案 0 :(得分:2)

如果要在程序运行时修改特定寄存器一次,可以使用调试器来完成,例如OllyDbg

如果要在程序未运行时修改代码,以便将来运行程序时行为不同,可以使用反汇编程序(如IDA)查看程序集。但是你还需要一些可以通过修改重新组合程序的东西,例如NAsm

您也可以使用Windows中的OpenProcess()函数将一个程序附加到另一个程序。然后,您可以读取和写入其他进程的任意值,包括修改它的代码。这是一个非常棘手的事情,设置和正常工作......这是调试器的工作方式,通常是相当复杂的软件。最好使用现有的,而不是尝试自己编写!

答案 1 :(得分:0)

据我所知,你想写一个程序:

  • 在某个地址(断点)停止另一个正在运行的程序
  • 等到达到断点
  • 读取某个寄存器的当前值
  • 将另一个值写入该寄存器
  • 断点后继续执行程序

不使用断点绝对没有意义,因为汇编寄存器在程序的不同部分用于完全不同的目的。因此,只有当其他程序在特定位置停止时,修改汇编寄存器才有意义。

在Windows,Win32代码(不是.NET代码)下,您可以通过以下方式进行操作:

  • 使用ol { display: inline-block; background-image: url("http://pixelbrush.ru/uploads/posts/2013-01/1359314378_0001-2.jpg"); background-size: cover ; background-repeat: no-repeat; }使用CreateProcess启动另一个.EXE文件(可能 - 更安全的是DEBUG_PROCESS)标记设置或...
  • ...使用CREATE_SUSPENDED调试已在运行的进程。
  • 使用DebugActiveProcessReadProcessMemory替换WriteProcessMemory0xCC)在断点地址处的汇编程序指令(正确:字节而不是指令)。
  • 如果您使用int3使用CREATE_SUSPENDED实际启动另一个.EXE文件
  • 调用ResumeThreadWaitForDebugEvent,直到达到断点。您可以使用ContinueDebugEvent来获取程序停止的位置。
  • 使用GetThreadContext
  • 替换原始指令的int3指令
  • 使用WriteProcessMemoryGetThreadContext修改寄存器。节点:在SetThreadContext指令后,int3寄存器必须递减!
  • 使用EIP让程序继续
  • 不幸的是,您的程序必须等待观察到的EXE文件的进一步调试事件并处理它们(ContinueDebugEventWaitForDebugEvent) - 即使您“只是”希望程序运行... < / LI>

如果要多次在此断点处停止程序,则会变得更加复杂:每次在断点之后继续时,必须在ContinueDebugEvent寄存器中设置“trace”标志,因此单步执行完成;在这一步之后,您必须再次用EFlags替换原始的汇编程序指令。

我自己多年前做过,因为我写的一些检查程序与Linux中的“strace”类似...

如果您使用的是C ++ .NET(或C#):有一个.NET程序集允许您执行所有这些操作,但使用此程序集并不比Win32变体更容易。

如果您只想将其用于教育用途:

不幸的是,Windows的调试API远不如Linux的调试API(int3)那么容易使用。如果您只是出于教育目的而想要这样做(并且您要检查的EXE文件是由您编写的)我会在Linux下执行此操作,而不是在Windows下执行此操作。然而,即使在Linux下,这也不是一件容易的事......