问题
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.
The code is very simple:
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!\n");
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;
Observations:
- 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.
Snapshots:
Visual studio can read the address
Can't read byte inside program
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"?
Why is this happening?
回答1:
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.
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.
来源:https://stackoverflow.com/questions/55858926/modifying-region-of-memory-returns-0xcc-vc