首页
社区
课程
招聘
[求助]怎么复制出正确的代码呢?
发表于: 2009-9-28 06:53 4733

[求助]怎么复制出正确的代码呢?

2009-9-28 06:53
4733
以下代码来自:http://bbs.pediy.com/showthread.php?t=85491
// 保存原来整个函数的代码
// pCode 用来保存代码的数组的地址
// TrgAddr 要保存的函数的地址
// BufferLength 整个函数占用的大小
VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength)
{
ULONG cAbs, i;
LONG oRel, cRel;

memset(pCode, 0x90, BufferLength);
for (i = 0; i < BufferLength; i++)
{
cAbs = TrgAddr + i;
pCode = *(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;
}*/
}

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;
}*/
}
}


805cb62c 8b00            mov     eax,dword ptr [eax]
805cb62e 8b00            mov     eax,dword ptr [eax]
805cb630 8945c0          mov     dword ptr [ebp-40h],eax
805cb633 33c0            xor     eax,eax
805cb635 40              inc     eax
805cb636 c3              ret
805cb637 8b45c0          mov     eax,dword ptr [ebp-40h]
805cb63a 8b65e8          mov     esp,dword ptr [ebp-18h]
805cb63d 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
====================================
使用BufferCode复制以上代码,复制后的结果如下:
====================================
ba5eebec 8b00            mov     eax,dword ptr [eax]
ba5eebee 8b00            mov     eax,dword ptr [eax]
ba5eebf0 8945c0          mov     dword ptr [ebp-40h],eax
ba5eebf3 33c0            xor     eax,eax
ba5eebf5 40              inc     eax
ba5eebf6 c3              ret
ba5eebf7 8b45c0          mov     eax,dword ptr [ebp-40h]
ba5eebfa 8b65e8          mov     esp,dword ptr [ebp-18h]
ba5eebfd c3              ret
ba5eebfe 17              pop     ss
ba5eebff fa              cli
ba5eec00 c5              ???


因为BufferCode是对比单个字节,发现E8则当做CALL来处理。结果在上面这种情况的时候,出错了。怎么做才能避免这样的情况复制出正确的代码呢?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
其实也不能算错,一般复制多了不会出问题,复制少了才麻烦
精确复制需要用反汇编引擎从函数头开始解析每个指令
2009-9-28 10:16
0
雪    币: 245
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
void func1()
{
...
...
}
void func1end()
{
}
func1size=(DWORD)func1end-(DWORd)func1;
memcpy(buff,func1,func1size)

为什么要奢易求难呢?
2009-11-23 22:58
0
雪    币: 362
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
opCode + 长度反汇编引擎 符合条件后才处理重定位数据. 3 楼的 memcpy 是搞不定重定位数据的.
2009-11-24 10:11
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
把原始代码搬到自己程序里执行
对付MP这类函数深层替换Call地址式hook效果不错  不过处理起来比较麻烦 ^-^

要个长度反汇编引擎 判断指令长度和机器码
Call判断就是  指令长度5  E8开头
精确复制不大可能 只多不少就好了
2009-11-24 16:37
0
雪    币: 8865
活跃值: (2379)
能力值: ( 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;
                }
        }
}
2010-3-13 20:32
0
游客
登录 | 注册 方可回帖
返回
//