首页
社区
课程
招聘
[原创]我的题目一做法
发表于: 2008-10-4 12:06 18910

[原创]我的题目一做法

2008-10-4 12:06
18910

已经过了保密时间,现在公开下我的做题答案,祥见附件。答案缺点是兼容性差,直接使用了LoadLibrary,GetProcAddress.FreeLibrary等函数地址。
优点当然是修改的地方少了。
恐怕函数占用字节数我是最多的了。呵呵,重在参与。这些不重要了。抛砖引玉吧。

1. 数据目录中添加导出表结构    20b0(6B0)
   在pediy.dll文件148h处添加字节:b0 20 00 00 45 00 00 00

2. 添加导出表   
在pediy.dll文件6b0处添加如下字节:用作导出表
    00 00 00 00 34 cf e5 48 00 00 00 00 e2 20 00 00
    01 00 00 00 01 00 00 00 01 00 00 00 d8 20 00 00
    dc 20 00 00 e0 20 00 00 20 11 00 00 ec 20 00 00
    00 00 70 65 64 69 79 2e 64 6c 6c 00 4f 70 65 6e
    55 72 6c 41 00

3. 添加导出函数
  在pediy.dll文件520h处添加机器码:
53 57 56 E8 00 00 00 00 5B 81 EB 28 11 40 00
8D B3 00 11 40 00 56 BF 77 1D 80 7C FF D7 50
5F 8D B3 10 11 40 00 56 57 B8 28 AC 80 7C FF  
D0 6A 01 6A 00 6A 00 8D B3 e0 10 40 00 56 8D  
B3 d0 10 40 00 56 6A 00 FF D0 57 B8 66 AA 80  
7C FF D0 5E 5F 5B C3

  在.text中添加常量字符串。
1) 在pediy.dll文件4e0h处添加:   68 74 74 70 3A 2F 2F 26  62 73 2E 70 65 64 69 79 2E 63 6F 6D 00
2) 在pediy.dll文件4d0h处添加:   6F 70 65 6E 00
3)  在pediy.dll文件500h处添加:   73 68 65 6C 6C 33 32 2E  64 6C 6C 00  
4)  在pediy.dll文件510h处添加:   53 68 65 6C 6C 45 78 65  63 75 74 65 41 00
到这里题目就完成了。

测试代码:
        HMODULE hd = LoadLibrary("pediy.dll");
        GetProcAddress(hd,"OpenUrlA");
        _asm call eax
        FreeLibrary(hd);


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (43)
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
本来我这样做。第一次提交
加了SHELLEXECUTEA
3X字节
003F10CA   .  60            pushad
003F10CB   .  E8 00000000   call    3.003F10D0 代码自身重定位
003F10D0  /$  58            pop     eax
003F10D1  |.  6A 00         push    0
003F10D3  |.  6A 00         push    0
003F10D5  |.  8BC8          mov     ecx, eax
003F10D7  |.  83C1 1C       add     ecx, 1C
003F10DA  |.  51            push    ecx
003F10DB  |.  83C1 06       add     ecx, 6
003F10DE  |.  51            push    ecx
003F10DF  |.  6A 00         push    0
003F10E1  |.  6A 01         push    1
003F10E3  |.  05 4C3F0000   add     eax, 3F4C
003F10E8  |.  FF10          call    dword ptr [eax] SHELLEXECUTEA
003F10EA  |.  61            popad
003F10EB  \.  C3            retn

后来
我加了2項重定位 还是用SHELLEXECUTEA
19字节
003F10CA   .  33C0          xor     eax, eax
003F10CC   .  50            push    eax                              ; /IsShown => 0
003F10CD   .  50            push    eax                              ; |DefDir => NULL
003F10CE   .  50            push    eax                              ; |Parameters => NULL
003F10CF   .  68 F2103F00   push    复件_(3).003F10F2                  ; |FileName = "http://bbs.pediy.com"  重定位
003F10D4   .  50            push    eax                              ; |Operation => NULL
003F10D5   .  50            push    eax                              ; |hWnd => NULL
003F10D6   .  FF15 AA203F00 call    dword ptr [<&SHELL32.ShellExecut>; \ShellExecuteA   重定位
003F10DC   .  C3            retn

后来 改了WINEXEC 汗 第2次提交
14字节
003F10CA   .  6A 01         push    1                                ; /ShowState = SW_SHOWNORMAL
003F10CC   .  68 F2103F00   push    复件_2.003F10F2        重定位            ; |CmdLine = "explorer.exe http://bbs.pediy.com"
003F10D1   .  FF15 08203F00 call    dword ptr [<&KERNEL32.WinExec>] 重定位 ; \WinExec
003F10D7   .  C3            retn

2008-10-4 12:21
0
雪    币: 184
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
003F10CA   .  6A 01         push    1                                ; /ShowState = SW_SHOWNORMAL

push eax就行,省1字节。显示状态随便为什么了,最后显示出来的是ieexplorer.exe.
2008-10-4 12:25
0
雪    币: 64
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
将输入表向下移位0x50。。在输入表前加入winexec参数1,就能压缩到12byte;
0600h: 65 78 70 6C 6F 72 65 72 2E 65 78 65 20 68 74 74  explorer.exe htt
0610h: 70 3A 2F 2F 62 62 73 2E 70 65 64 69 79 2E 63 6F  p://bbs.pediy.co
0620h: 6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  m...............
0630h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0640h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0650h: E2 20 00 00 D6 20 00 00 F3 20 00 00 00 00 00 00  . ... ... ......
0660h: BC 20 00 00 00 00 00 00 B4 20 00 00 00 00 00 00  . ....... ......
0670h: 00 00 00 00 CA 20 00 00 60 20 00 00 A4 20 00 00  ..... ..` ... ..
0680h: 00 00 00 00 00 00 00 00 FE 20 00 00 50 20 00 00  ......... ..P ..
0690h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
06A0h: 00 00 00 00 E2 20 00 00 D6 20 00 00 F3 20 00 00  ..... ... ... ..
06B0h: 00 00 00 00 BC 20 00 00 00 00 00 00 BE 01 4D 65  ..... ........Me
06C0h: 73 73 61 67 65 42 6F 78 41 00 55 53 45 52 33 32  ssageBoxA.USER32
06D0h: 2E 64 6C 6C 00 00 99 01 48 65 61 70 41 6C 6C 6F  .dll....HeapAllo
06E0h: 63 00 40 01 47 65 74 50 72 6F 63 65 73 73 48 65  c.@.GetProcessHe
06F0h: 61 70 00 00 00 57 69 6E 45 78 65 63 00 00 4B 45  ap...WinExec..KE
0700h: 52 4E 45 4C 33 32 2E 64 6C 6C 00 00 00 00 00 00  RNEL32.dll......

OpenUrlA 12 byte代码部分:
003C10CA >    B8 00203C00   mov     eax, 003C2000                    ;  ASCII "explorer.exe http://bbs.pediy.com"或cmd start命令也可
003C10CF      6A 05         push    5
003C10D1      50            push    eax
003C10D2      FF50 58       call    dword ptr [eax+58]
003C10D5      C3            retn

未添加节,没修改文件大小,可通用。

如果根据那测试程序的话,,可以压缩到更小。。但通用性不高,9byte也可以实现,但如果DLL进行初始化处理,就不能了。。
2008-10-4 12:26
0
雪    币: 64
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
push eax在我机器上无法通过。。通用性不高~
2008-10-4 12:31
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
难怪了。
原来是利用字串和函数地址的相对偏移。

等个位数字的放水
2008-10-4 12:34
0
雪    币: 184
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
运行了没反应?还是出错?
2008-10-4 12:34
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
用lordpe添加了一个导入函数WinExec
然后用WinExec("Explorer http://bbs.pediy.com", SW_SHOW);来打开网页
然后修改两处从定位表

感觉14个字节挺标准的,呵呵
6A 05          push    5                  ; /ShowState = SW_SHOW
68 47304000    push    0042201C           ; |CmdLine = "Explorer http://bbs.pediy.com"
FF15 17504000  call    dword ptr [<&KERNEL32.WinExec>]  ; \WinExec
C3             retn

本来想手动添加导入函数,但是没有经验,参考了书上的做法(用lordpe),
结果多了一个节,失败,呵呵。但在提交时才发现不添加节加分,哎,懒得再改了。
2008-10-4 12:36
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
我这里通过了
2008-10-4 12:37
0
雪    币: 243
活跃值: (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
思路太死了。。。

添加个输入函数不是更好?

代码中再搞个重定位

兼容性肯定没问题
2008-10-4 12:38
0
雪    币: 64
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
没反应,我这eax放的是函数OpenUrlA的地址,我当初还打算利用这个eax来定位。。这样就能压缩到9byte以内..但是aker说不通用~

还想过用hook的方法..但是好像非系统调用都要算在字节计算之内...
2008-10-4 12:39
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
添加好导出函数后,直接在导出表指向的函数地址处,直接写代码就行了? 我是用OD直接写的,老是调用不成功。
2008-10-4 12:41
0
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
13
12字节,将ShellExecuteEx的参数预先放在数据区,直接调用即可。数据区的布局用数组表示为如下:

//sizeof(SHELLEXECUTEINFO)=0x3c,15个DWORD
DWORD ShellEx[] = {
    0x0000003C, //1,cbSize
    0x00000000, //2
    0x00000000, //3
    0x00000000, //4
    0x00424a30, //5, lpFile,指向"http://bbs.pediy.com",地址需要重定位;
    0x00000000, //6
    0x00000000, //7
    0x00000000, //8
    0x00000000, //9
    0x00000000, //10
    0x00000000, //11
    0x00000000, //12
    0x00000000, //13
    0x00000000, //14
    0x00000000 //15   
};

在OpenUrlA函数填充的代码表示如下,实际可能略有不同,还需要重定位:

.text:00401000 68 58 60 40 00            push    offset ExecInfo         ; lpExecInfo
.text:00401005 FF 15 9C 50 40 00         call    ds:ShellExecuteExA
.text:0040100B C3                        retn

这种方法要添加输入表,输出表,重定位信息。但是没添加节,也没修改文件大小。
我想Aker大大说的12字节就是这样子吧,要压缩在个位数内并且通用,不知怎么弄了?
2008-10-4 12:44
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我差不多就是这么想的,只是没想到把字符串和导入函数连在一起,想楼上几位一样用偏移call。。。

我的14字节

003C10CA >/$  6A 01            push    1                                ; /ShowState = SW_SHOWNORMAL
003C10CC  |.  68 D8103C00      push    003C10D8                         ; |CmdLine = "explorer http://www.pediy.com"
003C10D1  |.  FF15 14203C00    call    dword ptr [<&KERNEL32.WinExec>]  ; \WinExec
003C10D7  \.  C3               retn
003C10D8   .  65 78 70 6C 6F 7>ascii   "explorer http://"
003C10E8   .  77 77 77 2E 70 6>ascii   "www.pediy.com",0

添加了一个引入函数 WinExec,添加了2个重定位地址
2008-10-4 12:51
0
雪    币: 282
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
函数的大小关键在--使用哪个api
13楼的Api这样使用

0100739D >    B8 56341200   mov     eax, 123456
010073A2      50            push    eax
010073A3      FF50 70       call    dword ptr [eax+70]
010073A6      C3            retn

这样会省一个字节
10字节。

我是用错了api的
2008-10-4 12:57
0
雪    币: 558
活跃值: (43)
能力值: ( LV12,RANK:220 )
在线值:
发帖
回帖
粉丝
16
2008-10-4 12:59
0
雪    币: 243
活跃值: (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
[QUOTE=vxasm;516382]12字节,将ShellExecuteEx的参数预先放在数据区,直接调用即可。数据区的布局用数组表示为如下:

//sizeof(SHELLEXECUTEINFO)=0x3c,15个DWORD
DWORD ShellEx[] = {
    0x0000003C, //1,cbSize
...
.text:00401000 68 58 60 40 00            push    offset ExecInfo         ; lpExecInfo
.text:00401005 FF 15 9C 50 40 00         call    ds:ShellExecuteExA
.text:0040100B C3                        retn
[/QUOTE]

可以再压缩下,弄到10bytes

mov eax,lpExecInfo
push eax
call [eax+xx]
retn
2008-10-4 13:02
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
[QUOTE=xiep;516390]我的解答 http://bbs.pediy.com/showthread.php?t=73884[/QUOTE]

没权限是看不了的
2008-10-4 13:05
0
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
19
15楼说的没错,这样可以少2字节,当时没想到这样使用。
2008-10-4 13:06
0
雪    币: 558
活跃值: (43)
能力值: ( LV12,RANK:220 )
在线值:
发帖
回帖
粉丝
20
贴一下
1,构造数据
004020C0  WinExec函数地址(4字节),WinExec导入表的FirstThunk指向这个双字
004020C4  0
004020C8  explorer.exe http://bbs.pediy.com/
004020EA

2,构造指令序列(12字节)
004010D0   .  6A 01         push    1
004010D2   .  B8 C8204000   mov     eax, pediy.004020C8   ;  ASCII "explorer.exe http://bbs.pediy.com/"
004010D7   .  50            push    eax
004010D8   .  FF50 F8       call    dword ptr [eax-8]	  ;  kernel32.WinExec
004010DB   .  C3            retn

3,添加WinExec的导入项
略

4,添加重定位项
如步骤2,004010D3处需要重定位

5,添加导出函数
导出函数为OpenUrlA

说明:未添加新节,未增大文件大小

上传的附件:
2008-10-4 13:10
0
雪    币: 282
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
1。ShellExecuteExA
2。WinExec
3。ShellExecuteA
2008-10-4 13:12
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
22
原来是把参数给移出去了,实在没想到...
我开始也是搜索LoadLibraryA来着,不过通过PEB搜Kernel32基址,代码比LZ的还要长...不过这个确实稳定。

长见识了,ShellExecuteExA()这个API,只用压一次参数,比WinExec还省...

可怜我CreateProcessA写了40多字节
003F10CA   .  60            PUSHAD
003F10CB   .  6A 44         PUSH 44                                  ;  _STARTUPINFO.cb = 44
003F10CD   .  B9 10000000   MOV ECX,10                               ;  压入40字节的0作为缓冲区
003F10D2   >  6A 00         PUSH 0
003F10D4   .^ E2 FC         LOOPD SHORT pediy.003F10D2
003F10D6   .  54            PUSH ESP                                 ; /pProcessInfo
003F10D7   .  54            PUSH ESP                                 ; |pStartupInfo
003F10D8   .  6A 00         PUSH 0                                   ; |CurrentDir = NULL
003F10DA   .  6A 00         PUSH 0                                   ; |pEnvironment = NULL
003F10DC   .  6A 00         PUSH 0                                   ; |CreationFlags = 0
003F10DE   .  6A 00         PUSH 0                                   ; |InheritHandles = FALSE
003F10E0   .  6A 00         PUSH 0                                   ; |pThreadSecurity = NULL
003F10E2   .  6A 00         PUSH 0                                   ; |pProcessSecurity = NULL
003F10E4   .  68 80303F00   PUSH 003F3080                            ; |CommandLine = "-e bbs.pediy.com"
003F10E9   .  68 50303F00   PUSH 003F3050                            ; |ModuleFileName = "C:\Program Files\Internet Explorer\iexplore.exe"
003F10EE   .  FF15 5D503F00 CALL DWORD PTR DS:[<&KERNEL32.CreateProc>; \CreateProcessA
003F10F4   .  83C4 44       ADD ESP,44                               ;  修正之前压入的44字节
003F10F7   .  61            POPAD
003F10F8   .  C3            RETN


2008-10-4 13:14
0
雪    币: 260
活跃值: (102)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
23
20多个字节才实现的,当时没想到WinExec,字节全都用在传递参数上了。
2008-10-4 13:24
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
“添加了2个重定位地址”这个是怎么找啊?我的思路和你的基本一样,就是不会弄那个重定位。麻烦给解释下吧
2008-10-4 13:24
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
学习到了,为了减少参数占字节可以把参数事先写在一个地方,然后push
为了减少call字节数,要把call的内容写在参数附近,这样可以直接计算得到函数地址
2008-10-4 13:28
0
游客
登录 | 注册 方可回帖
返回
//