修改内存区域 - 返回 0xCC VC++
我正在修改在 dll 中编译的可执行代码的某些部分.但是我正在修改的整个段的固定地址上的单个字节无法更改,甚至无法读取.
I am modifying some sections of an executable code compiled in a dll. But a single byte at a fixed address from the entire segment that I am modifying can't be changed, not even read.
代码很简单:
SEGMENT_DATA segInfo = getSegmentInfo(mHandle, segmentName);
if (segInfo.inFileSegmentAddr == 0) return false;
DWORD mOlProtection;
DWORD mOlProtection_1;
if (segInfo.architecture != MY_ARCH) {
printf(" Not the same architecture!
");
return 0;
}
if(VirtualProtect((LPVOID)segInfo.segmentAddr, segInfo.segmentSize, PAGE_EXECUTE_READWRITE, &mOlProtection)==0) return false;
DWORD i=0;
for (size_t k = 0; k < segInfo.segmentSize; k++) {
BYTE *lpByteValue = (BYTE*)(segInfo.segmentAddr + k);
BYTE temp = *lpByteValue;
*lpByteValue = temp ^ lDecryptionKey[i];
i++;
i %= decryptionKeyLength;
}
if(VirtualProtect((LPVOID)segInfo.segmentAddr, segInfo.segmentSize, mOlProtection, &mOlProtection_1)==0) return false;
观察:
- 在修改内存之前,我使用
PAGE_EXECUTE_READWRITE
标志取消保护"该区域. - Visual Studio 中的内存视图清楚地向我展示了该特定地址的价值.更奇怪的是,在第二次我从调试器手动修改值时,我的代码也能够更改该值.
- 示例代码中的
temp
变量包含值0xCC
- 在数百个其他字节的海洋中,这个字节实际上是唯一不变的.它是内存视图中唯一标记为黑色的字节(其余为红色,因为它们已更改)
- Dll 在 Debug/x86 中编译./MTd 标志设置.没有随机地址(/DYNAMICBASE : NO ,/FIXED: NO).没有整个程序优化.
- 未修改的字节不是变量.所以它不能未初始化".它实际上是一个非常重要的字节:它是指令操作码.一切都在该字节上崩溃.
- 解密例程(XOR 码)对错误没有影响.我进入代码并在
temp
到达xor
之前查看它的值.这意味着解密密钥从未使用过,因此不会导致问题. - 虚拟保护成功.
- Before I modify the memory, I "unprotect" the region with
PAGE_EXECUTE_READWRITE
flag. - Memory View in visual studio clearly shows me the value at that particular address. Even weirder is that in the second I modify the value manually from the debugger, my code is also able to change that value.
temp
variable in the example code contains the value0xCC
- This byte is literally the only one unchanged in a sea of hundred other bytes. It is the only byte marked black in Memory View (the rest are red because they were changed)
- Dll is compiled in Debug/x86 . /MTd flag set. No random address (/DYNAMICBASE : NO , /FIXED: NO). No Whole program optimization.
- The unmodified byte IS NOT a variable. So it can't be "uninitialized". It is actually a very important byte: it is the instruction opcode. Everything crashes on that byte.
- The decryption routine (XOR code) has no effect on the error. I step into the code and look at
temp
's value before it reaches thexor
. This means the decryption key is never used and therefore it can't cause the problem. - Virtual protect succeeds.
快照:
Visual Studio 可以读取地址
Visual studio can read the address
无法读取程序内的字节
我知道导致问题的不是该单个地址处的字节值(因为我发现其他具有相同值的字节已成功处理).也许字节仍然受保护"?
I know it's not the value of the byte at that single address that is causing problems (because I found other bytes with the same value that were processed successfully). Perhaps the byte is still "protected"?
为什么会这样?
推荐答案
你可以很好地处理一个非常常见的软件断点
场景.软件断点
实际上是通过用断点指令替换要断点的指令来设置的.
You could very well deal with a very common scenario of Software Breakpoints
.
Software breakpoints
are in fact set by replacing the instruction to be breakpointed with a breakpoint instruction.
断点指令存在于大多数 CPU 中,并且通常与最短指令一样短,因此只有 x86 上的一个字节(0xCC,INT 3)
.
The breakpoint instruction is present in most CPUs, and usually as short as the shortest instruction, so only one byte on x86 (0xCC, INT 3)
.
由于我不知道您的源代码中是否有任何断点,我只能假设这是您的问题.
As I don't know if there are any breakpoints at all in your source I can only assume that this is your problem.
相关文章