能力值:
( LV2,RANK:10 )
|
-
-
2 楼
其实也不能算错,一般复制多了不会出问题,复制少了才麻烦
精确复制需要用反汇编引擎从函数头开始解析每个指令
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
void func1()
{
...
...
}
void func1end()
{
}
func1size=(DWORD)func1end-(DWORd)func1;
memcpy(buff,func1,func1size)
为什么要奢易求难呢?
|
能力值:
( LV7,RANK:100 )
|
-
-
4 楼
opCode + 长度反汇编引擎 符合条件后才处理重定位数据. 3 楼的 memcpy 是搞不定重定位数据的.
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
把原始代码搬到自己程序里执行
对付MP这类函数深层替换Call地址式hook效果不错 不过处理起来比较麻烦 ^-^
要个长度反汇编引擎 判断指令长度和机器码
Call判断就是 指令长度5 E8开头
精确复制不大可能 只多不少就好了
|
能力值:
( LV12,RANK:760 )
|
-
-
6 楼
使用LDASM的代码版本
// OrgRel 原相对跳转地址
// CurAbs 当前代码绝对地址
// MyAbs 替换代码绝对地址
// CodeLen 跳转代码占据的长度
// 返回值 到替换代码的相对地址
LONG GetRelAddr(LONG OrgRel, ULONG CurAbs, ULONG MyAbs) //, ULONG CodeLen)
{
ULONG TrgAbs;
TrgAbs = CurAbs + OrgRel; // + CodeLen; //目的地址
return TrgAbs - MyAbs;
}
// 保存原来整个函数的代码
// pCode 用来保存代码的数组的地址
// TrgAddr 要保存的函数的地址
// BufferLength 整个函数占用的大小
VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength)
{
ULONG cAbs, i;
LONG oRel, cRel;
PUCHAR pOpcode;
LONG CodeLen =0 ;
memset(pCode, 0x90, BufferLength);
for (i = 0; i < BufferLength; i+=CodeLen)
{
cAbs = TrgAddr + i;
CodeLen = SizeOfCode(pCode,&pOpcode);
memcpy(pCode + i,(void *)cAbs,CodeLen);
//pCode[i] = *(PUCHAR)cAbs;
switch (*(PUCHAR)cAbs)
{
case 0x0F: //JXX NEAR X
if ((*(PUCHAR)(cAbs + 1) >= 0x80)&&(*(PUCHAR)(cAbs + 1) <= 0x8F))
{
oRel = *(PLONG)(cAbs + 2);
if ((oRel + cAbs + 6 > TrgAddr + BufferLength)||
(oRel + cAbs + 6 < TrgAddr)) //判断跳转是否在过程范围内
{
pCode[i + 1] = *(PUCHAR)(cAbs + 1);
cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);
memcpy(pCode + i + 2, &cRel, sizeof(LONG));
//DbgPrint("JXX: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);
//i += sizeof(LONG) + 1;
}
}
break;
case 0xE8: //CALL
oRel = *(PLONG)(cAbs + 1);
if ((oRel + cAbs + 5 > TrgAddr + BufferLength)||
(oRel + cAbs + 5 < TrgAddr)) //判断跳转是否在过程范围内
{
cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);
memcpy(pCode + i + 1, &cRel, sizeof(LONG));
//DbgPrint("CALL: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);
//i += sizeof(LONG);
}
break;
case 0x80: //CMP BYTE PTR X
if (*(PUCHAR)(cAbs + 1) == 0x7D)
{
memcpy(pCode + i + 1, (PVOID)(cAbs + 1), 3);
//i += 3;
continue;
}
break;
case 0xC2: //RET X
if (*(PUSHORT)(cAbs +1) == 0x10)
{
memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));
//i += sizeof(USHORT);
}
break;
case 0xE9: //JMP
oRel = *(PLONG)(cAbs + 1);
if (oRel + cAbs > TrgAddr + BufferLength)
{
cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);
memcpy(pCode + i + 1, &cRel, sizeof(LONG));
//i += 4;
}
break;
}
if ((*(PUCHAR)cAbs == 0x39)||(*(PUCHAR)cAbs == 0x89)||(*(PUCHAR)cAbs == 0x8D))
{
memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));
//i += sizeof(USHORT);
continue;
}
if ((*(PUCHAR)cAbs >= 0x70)&&(*(PUCHAR)cAbs <= 0x7F)&&(*(PUCHAR)(cAbs - 1) != 0xFF))
{
oRel = (LONG)(*(PCHAR)(cAbs + 1));
cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);
memcpy(pCode + i + 1, &cRel, 1);
//i++;
continue;
}
}
}
|