通用Thunk
2010-07-15 20:45:23 来源:WEB开发网2.转移指令的目的地
许多转移指令的目的地使用“到源的偏移量”来表示
比如:当CPU 执行到0xFF000000 处的指令时, 指令像这个样子:0xFF000000 : 0xE9 0x33 0x55 0x77 0x99
0xFF000005 : ...
0xE9 是一个 JMP 指令,紧接着的4字节将被解释为偏移
offset = 0x99775533 (在Intel x86 机器上,低字节存储在低地址上) = -1720232653
源 (src) = 0xFF000000 (JMP指令的地址) = 4278190080
目的地 (dst) = src+offset+5 (JMP占1字节,偏移占4字节) = 4278190080 – 1720232653 +5 = 2557957432 = 0x98775538
所以在指令 “ JMP -1720232653 “ 之后,下一条被执行的指令将在
0x98775538 : ...
基于这点,我们可以实现2个方法:
void SetTransterDST(
void *src /* the address of transfer instruction*/
,int dst /* the destination*/ ) {
unsigned char *op = static_cast<unsigned char *>(src);
switch (*op++) {
case 0xE8: // CALL offset (dword)
case 0xE9: // JMP offset (dword)
{
int *offset = reinterpret<int*>(op);
*offset = dst – reinterpret<int>(src) - sizeof(*op)*1 – sizeof(int);
}
break;
case 0xEB: // JMP offset (byte)
...
break;
case ...:
...
break;
default :
assert(!”not complete!”);
}
}
int GetTransnferDST(const void *src) {
const unsigned char *op = static_cast< const unsigned char *>(src);
switch (*op++) {
case 0xE8: //CALL offset (dword)
case 0xE9: //JMP offset (dword)
{
const int *offset = reinterpret_cast<const int*>(op);
return *offset + PointerToInt32(src) + sizeof(*op) +sizeof(int);
}
break;
case 0xEB: // JMP offset(byte)
...
break;
case ...:
...
break;
default:
assert(!”not complete!”);
break;
}
return 0;
}
更多精彩
赞助商链接