首页
社区
课程
招聘
[原创]stolen code 最简单的实现--jmp 乱序
2007-8-18 20:01 11053

[原创]stolen code 最简单的实现--jmp 乱序

dummy 活跃值
23
2007-8-18 20:01
11053
//在 x 中查找 y, 查找成功索引,否则返回 -1
static DWORD _2find(DWORD x[], DWORD l, DWORD y)
{
        DWORD low, high, mid;

        low = 0;
        high = l - 1;
        while ( low <= high )
        {
                mid = (high + low) >> 1;
                if ( x[mid] == y )
                        return mid;

                if ( y > x[mid] )
                        low = mid + 1;
                else
                        high = mid - 1;
        }

        return -1;
}

/*
CONTS PBYTE psrc 要抽代码的地方
PBYTE pdst 代码经过处理后存放的地方
DWORD Offset 被抽代码和存放代码之间偏移,注:不一定是 pdst - psrc, 有些难表达
int line 要抽的代码行数
返回第一条指令的位置
*/
//打乱原始指令序列
/*
DWORD StolenCode(CONST PBYTE psrc, PBYTE pdst, DWORD offset, DWORD line, PDWORD size)
{
        DWORD a[100], b[100], l[100];

        PBYTE p1, p2;
        DWORD i, j;

        j = 0;
        for ( i = 0; i < line; ++i )
        {
                a[i] = j;        //原始指令的原始偏移位置
                b[i] = (DWORD)-1;
               
                xde_instr instr;
                l[i] = xde_disasm(psrc + j, &instr); //获取指令长度
                if ( l[i] == 0 )
                        break;

                j += l[i];
        }

        p2 = pdst;
        for ( j = 0; j < i; ++j ) //打乱指令顺序,然后用 jmp 指令串连起来
        {
                int k;
                do {
                        k = rand() % i;
                } while ( b[k] != (DWORD)-1 );
               
                p1 = psrc + a[k];
                b[k] = p2 - pdst + 1;

                if ( *p1 == 0xEB ) { //把短跳转指令修改为长跳转指令
                        p2 += 3; // 3 = 5 - l[k]
                }
                else if ( *p1 >= 0x70 && *p1 <= 0x7F ) {
                        p2 += 4; // 4 = 6 - l[k]
                }
                else if ( *p1 == 0xE2 ) {
                        p2 += 5; //5 = 7 - l[k]
                }
                else if ( *p1 == 0xE3 ) { //jcxz
                        p2 += 6; //6 = 8 - l[k]
                }
                else if ( *p1 == 0xE0 || *p1 == 0xE1 ) {
                        p2 += 7; //7 = 9 - l[k]
                }
                else {
                        *p2++ = (BYTE)rand(); //junk
                        memcpy(p2, p1, l[k]);
                }
               
                p2 += l[k] + 5;
        }
        *size = p2 - pdst; //变化后数据实际大小

        for ( j = 0; j < i; ++j ) //修正跳转
        {
                DWORD  w1 = l[j];
                DWORD  w2 = l[j];

                p1 = psrc + a[j];
                p2 = pdst + b[j];
                if ( *p1 == 0xEB || (*p1 >= 0x70 && *p1 <= 0x7F) || (*p1 >= 0xE0 && *p1 <= 0xE3) ) //8 位相对跳转
                {
                        if ( *p1 == 0xEB )
                        {
                                w2 = 5; //修改模式后, 这条指令的长度
                                *p2++ = 0xE9;
                        }
                        else if ( *p1 >= 0x70 && *p1 <= 0x7F )
                        {
                                w2 = 6;
                                *p2++ = 0x0F;
                                switch ( *p1 )
                                {
                                case 0x70: *p2 = 0x80; break;        //jo rel8                --> jo rel32
                                case 0x71: *p2 = 0x81; break;        //jno rel8                --> jno rel32
                                case 0x72: *p2 = 0x82; break;        //jnae rel8                --> jnae rel32
                                case 0x73: *p2 = 0x83; break;        //jnb rel8                --> jnb rel32
                                case 0x74: *p2 = 0x84; break;        //jz rel8                --> jz rel32
                                case 0x75: *p2 = 0x85; break;        //jnz rel8                --> jnz rel32
                                case 0x76: *p2 = 0x86; break;        //jna rel8                --> jna rel32
                                case 0x77: *p2 = 0x87; break;        //jnbe rel8                --> jnbe rel32
                                case 0x78: *p2 = 0x88; break;        //js rel8                --> js rel32
                                case 0x79: *p2 = 0x89; break;        //jns rel8                --> jns rel32
                                case 0x7A: *p2 = 0x8A; break;        //jp rel8                --> jp rel32
                                case 0x7B: *p2 = 0x8B; break;        //jpo rel8                --> jpo rel32
                                case 0x7C: *p2 = 0x8C; break;        //jnge rel8                --> jnge rel32
                                case 0x7D: *p2 = 0x8D; break;        //jnl rel8                --> jnl rel32
                                case 0x7E: *p2 = 0x8E; break;        //jng rel8                --> jng rel32
                                case 0x7F: *p2 = 0x8F; break;        //jnle rel8                --> jnle rel32
                                }

                                ++p2;
                        }
                        else
                        {
                                switch ( *p1 )
                                {
                                case 0xE0:
                                        //loopne -->
                                        //$                        jz                $ + 8
                                        //$ + 2                dec                ecx
                                        //$ + 3                jnz                xxxxxxxx
                                        //$ + 8                ????????????????
                                        *p2++ = 0x74; *p2++ = 0x07; *p2++ = 0x49; *p2++ = 0x0F; *p2++ = 0x85;
                                        w2 = 9;
                                        break;

                                case 0xE1:
                                        //loope        -->
                                        //$                        jnz                $ + 8
                                        //$ + 2                dec                ecx
                                        //$ + 3                jnz                xxxxxxxx
                                        //$ + 8                ????????????????
                                        *p2++ = 0x75; *p2++ = 0x07; *p2++ = 0x49; *p2++ = 0x0F; *p2++ = 0x85;
                                        w2 = 9;
                                        break;

                                case 0xE2:
                                        //loop                -->
                                        //$                        dec                ecx
                                        //$ + 1                jnz                xxxxxxxx
                                        *p2++ = 0x49; *p2++ = 0xF; *p2++ = 0x85;
                                        w2 = 7;
                                        break;

                                case 0xE3:
                                        //jcxz                -->
                                        //$                        test        ecx, ecx
                                        //$ + 2                jz                xxxxxxxx
                                        *p2++ = 0x85; *p2++ = 0xC9; *p2++ = 0x0F; *p2++ = 0x84;
                                        w2 = 8;
                                }
                        }

                        DWORD k = _2find(a, i, a[j] + (char)p1[1] + l[j]);
                        if ( (DWORD)-1 == k )
                        {        //目标指令没有抽到
                                DWORD z = offset + b[j] - a[j] + w2 - w1 - (char)p1[1];
                                *(PDWORD &)p2 = 0 - z;
                        }
                        else {
                                *(PDWORD &)p2 = b[k] - b[j] - w2;
                        }
                        p2 += sizeof (DWORD);
                }
                else if ( *p1 == 0xE9 || *p1 == 0xE8 || (*(PDWORD)p1 >= 0x800F && *(PDWORD)p1 <= 0x8F0F) ) //32 位相对跳转
                {
                        DWORD k = _2find(a, i, a[j] + *(PDWORD)(p1 + 1) + l[j]);

                        p2 += l[j] == 5 ? 1 : 2;
                        if ( (DWORD)-1 == k )
                        {
                                DWORD z = offset + b[j] - a[j] - *(int*)(p1 + 1);
                                *(PDWORD &)p2 = 0 - z;
                        }
                        else {
                                *(PDWORD &)p2 = b[k] - b[j] - w1;
                        }
                        p2 += sizeof (DWORD);
                }
                else {
                        p2 += l[j];
                }
               
                DWORD z = offset + b[j] - a[j] + 5 + w2 - w1;

                *p2++ = 0xE9;
                *((PDWORD &)p2)++ = j == i - 1 ? 0 - z : b[j + 1] - b[j] - w2 - 5; //修改 jmp 跳转
        }

        return b[0];
}

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞8
打赏
分享
最新回复 (15)
雪    币: 226
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
十三少 2 2007-8-19 12:21
2
0
太强大了,支持一个.
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 2007-8-19 12:32
3
0
下来研究一下,支持
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2007-8-19 15:40
4
0
不错,强!~
雪    币: 29412
活跃值: (18670)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2007-8-19 15:51
5
0
dummy功底扎实
雪    币: 182
活跃值: (50)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
pathletboy 2 2007-8-19 20:52
6
0
楼主一天一篇精华.值得敬佩.高产期哈,再接再厉
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
紫色的魚 2007-8-20 01:21
7
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2007-8-20 12:54
8
0
前几个月也试过这个,对原程序整个乱序,再实现代码变形,不过问题多多.
主要是分不清代码与数据.

XDE和Mistfall是好东西,不过都有些小bug
雪    币: 214
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
RyoKou 1 2007-8-20 14:38
9
0
lz和ls都是猛将兄。。。。
雪    币: 255
活跃值: (266)
能力值: ( LV12,RANK:220 )
在线值:
发帖
回帖
粉丝
WiNrOOt 5 2007-8-20 16:35
10
0
变形指定的一段,就够了。
雪    币: 1726
活跃值: (721)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
yijun8354 12 2007-8-20 20:33
11
0
新一轮灌水哦~~
雪    币: 8044
活跃值: (4335)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sunsjw 1 2007-8-21 23:54
12
0
好东西啊,值得学习一翻。。。
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
八连人 2007-9-10 11:09
13
0
弱弱的问一句,是放到OllyIce的script里执行吗?谢谢!
雪    币: 314
活跃值: (15)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
王仁军 10 2007-9-14 11:53
14
0
[QUOTE=dummy;347322]//在 x 中查找 y, 查找成功索引,否则返回 -1
static DWORD _2find(DWORD x[], DWORD l, DWORD y)
{
      xde_instr instr;
      l[i] = xde_disasm(psrc + j, &instr); //获取指令长度
    if ( l[i] == 0 )

[/QUOTE]

上面的 xde_instr   、 xde_disasm   是什么模样?,怎么没看到定义呢?
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jollygrass 2007-9-14 17:00
15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sorckey 2007-9-15 21:19
16
0
今天没有时间研究,下下来慢慢欣赏
游客
登录 | 注册 方可回帖
返回