问题
I want to modify the value of a register that is in a certain program. The only problem is, I don't know how to access it. If there is a way, how do I read/write into it? (preferred language C++)
回答1:
If you want to modify a particular register one time while the program is running you can do so using a debugger, such as OllyDbg.
If you want to modify the code while the program isn't running, such that in the future when you run the program it behaves differently, you can view the Assembly using a disassembler such as IDA. But you'll also need something that can reassemble the program with your modifications, such as NAsm
You can also attach one program to another while both are running using the OpenProcess() function in windows. You can then read and write arbitrary values to the other process, including modifying it's code. This is a pretty tricky thing to set up and have work properly... It's how debuggers work, which are usually pretty complex pieces of software. Better to use an existing one than to try to write your own!
回答2:
As far as I understand you correctly you want to write a program that:
- Stops another running program at a certain address (breakpoint)
- Waits until the breakpoint is reached
- Reads the current value of a certain register
- Writes another value into that register
- Continues program execution after the breakpoint
Not using a breakpoint makes absolutely no sense because the assembly registers are used for completely different purposes in different parts of the program. So modifying an assembly register only makes sense when the other program is stopped at a specific position.
Under Windows, Win32 code (not .NET code), you may du this the following way:
- Start the other .EXE file using
CreateProcesswith theDEBUG_PROCESS(and maybe - what would be more safe - theCREATE_SUSPENDED) flag set or... - ...use
DebugActiveProcessto debug an already running process. - Use
ReadProcessMemoryandWriteProcessMemoryto replace the assembler instruction (to be correct: the byte and not the instruction) at the breakpoint address by0xCC(int3). - If you used
CREATE_SUSPENDEDuseResumeThreadto actually start the other .EXE file - Call
WaitForDebugEventandContinueDebugEventuntil the breakpoint is reached. You may useGetThreadContextto get the location where the program is stopped. - Replace the
int3instruction by the original instruction usingWriteProcessMemory - Use
GetThreadContextandSetThreadContextto modify registers. Node: After anint3instruction theEIPregister must be decremented! - Use
ContinueDebugEventto let the program continue - Unfortunately your program has to wait for further debugging events of the observed EXE file and handle them (
WaitForDebugEventandContinueDebugEvent) - even if you "just" want the program to run...
If you want to stop the program at this breakpoint multiple times it is becoming more complicated: You must set the "trace" flag in the EFlags register each time you continue after the breakpoint so a single-step is done; after that single step you have to replace the original assembler instruction by int3 again.
I myself did this years ago because I wrote some inspection program for that worked similar to "strace" in Linux...
If you are using C++.NET (or C#): There is a .NET assembly that allows you doing all this but using this assembly is not easier than the Win32 variant.
If you want to do this for educational uses only:
Unfortunately the debugging API of Windows is by far less easy to use then the debugging API (ptrace) of Linux. If you just want to do this for educational purposes (and the EXE file you want to inspect is written by you) I would do this excercice under Linux, not under Windows. However even under Linux this is not an easy job...
来源:https://stackoverflow.com/questions/32418677/how-can-you-read-write-asm-registers-from-an-exe-using-c