找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 11156|回复: 10

使用ASM编写没有导入表的EXE

 火.. [复制链接]

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2010-8-5 22:43:29 | 显示全部楼层 |阅读模式
本帖最后由 Tesla.Angela 于 2010-8-5 22:55 编辑

  1. .386
  2. .model flat, stdcall
  3. option casemap :none
  4. .data
  5. DllName db 'user32.dll',0
  6. FunName db 'MessageBoxA',0
  7. .CODE
  8. START:
  9. NoImport proc
  10.   local hLib:DWORD
  11.   local pMsg:DWORD
  12.   ;hLib=LoadLibraryA("user32.dll")
  13.   push offset DllName
  14.   mov eax,7C801D7Bh
  15.   call eax
  16.   mov hLib,eax
  17.   ;pMsg=GetProcAddress(hLib,"MessageBoxA")
  18.   push offset FunName
  19.   push hLib
  20.   mov eax,7C80AE40h
  21.   call eax
  22.   mov pMsg,eax
  23.   ;MessageBoxA(0,"MessageBoxA","user32.dll",0)
  24.   push 0
  25.   push offset DllName
  26.   push offset FunName
  27.   push 0
  28.   mov eax,77D507EAh
  29.   call eax
  30.   ;ExitProcess(0)
  31.   push 0
  32.   mov eax,7C80C0F8h
  33.   call eax
  34. NoImport endp
  35. end START
复制代码

不知道有没有不使用硬编码实现的办法?
这段代码编译出来的EXE大小为1.5KB。
如果注释掉NoImport proc到NoImport endp之间的代码也可以编译,编译出来的EXE大小为1KB,但是运行时出错。

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
 楼主| 发表于 2010-8-5 22:46:42 | 显示全部楼层
我用来查API地址的小软件

API地址专家.rar

195.04 KB, 下载次数: 7635

0

主题

1

回帖

0

精华

初来乍到

积分
15
发表于 2010-8-6 00:33:03 | 显示全部楼层
本帖最后由 mxxgt 于 2010-8-6 00:38 编辑

  1. ;注意masm编译,注意这个程序不能直接运行,编译完成后od加载code3之前运行一次是加密,运行完dump出来就是shellcode了!
  2. .386p
  3. .model flat, stdcall
  4. .code
  5. start:
  6. assume fs:flat, gs:flat
  7. ;这里直接写代码
  8. ;------------------------B.j.H's split-line-----------------------------------
  9. ;首先建立一个在shellcode中需要用到的字符表他应该包括
  10. ;LoadLibraryA
  11. ;user32
  12. ;MessageBoxA
  13. ;ExitProcess
  14. ;B.J.H        当然为了弹出的Msgbox有个性可以添加这样一字符串,用来弹框框
  15. ;这些字符统统压入堆栈以便调用!
  16. ;所以我们代码的前面是
  17. ;------------------------B.j.H's split-line-----------------------------------
  18. push 0048h                        ;B.J.H
  19. push 2e4a2e42h                    ;
  20. push 00737365h                    ;ExitProcess
  21. push 636f7250h
  22. push 74697845h
  23. push 0041786fh                    ;MessageBoxA
  24. push 42656761h
  25. push 7373654dh
  26. push 00323372h                    ;user32
  27. push 65737500h
  28. push 41797261h                    ;LoadLibraryA
  29. push 7262694ch
  30. push 64616f4ch
  31. mov edx,esp                       ;保存字符串首地址
  32. ;上面是一个函数表!注意压入的字符格式,注意堆栈是倒过来的!慢慢调试可以感觉出来的!
  33. ;最后一据代码是保存字符串表的的入口(也就是首地址)
  34. ;------------------------B.j.H's split-line-----------------------------------
  35. ;获得Kernel的基地址(这一段很多地方都能找到!)不做解释了!
  36. xor eax,eax
  37. mov eax,dword ptr FS:[030h]
  38. mov eax,DWORD PTR [eax+0ch]
  39. mov esi,DWORD PTR [eax+01ch]
  40. lodsd
  41. mov eax,dword ptr [eax+8h]
  42. ;------------------------B.j.H's split-line-----------------------------------
  43. ;现在eax中存放的就是kernel32的基地址了!
  44. ;当处到这里我就不知道该怎么出来了!得到基地址到底有什么用呢!不知道!呵呵!时间久了!
  45. ;忙忙的阅读一些资料!自然而然的就懂了!...我不是那种一看资料就明白的那种具有潜质的大
  46. ;鸟,只是一点一点体会的小菜鸟!
  47. ;下面先写一个调用就是
  48. ;------------------------B.j.H's split-line-----------------------------------
  49. push eax                          ;保存kernel32.dll基地址
  50. push edx                          ;传入需要查询函数名地址
  51. push 0ch                          ;函数名长度
  52. call getapi                       ;调用函数得到函数入口
  53. ;------------------------B.j.H's split-line-----------------------------------
  54. pop ebx                           ;弹出堆栈里的的函数名地址(是之前建立的)
  55. add ebx,0dh                    ; 加上字符长度得到下一个需要使用的字符串的
  56. push ebx                         ;参数"user32"
  57. call eax                           ;调用LoadLibraryA("user32"),加载
  58.                                        ;user32.dll,且eax中是从函数调用返回的user32的基地址
  59. ;------------------------B.j.H's split-line-----------------------------------
  60. add ebx,07h                     ; 继续得到下一个需要使用的字符串。下面的几个调用不详细说了... ...
  61. push ebx                          ;
  62. push 0bh                          ;  
  63. call getapi                        ;调用getaddr函数获取MessageBoxA函数地址.
  64. ;------------------------B.j.H's split-line-----------------------------------
  65. pop ebx                           ;
  66. add ebx,018h                   ;
  67. push 0h                           ;
  68. push ebx                          ;
  69. push ebx                          ;
  70. push 0h                           ;
  71. call eax                          ;调用MessageBoxA
  72. ;------------------------B.j.H's split-line-----------------------------------
  73. mov edx,0ch                     ;
  74. pop eax                            ;
  75. sub ebx,edx                      ;
  76. push ebx                          ;
  77. push edx                          ;
  78. call getapi                        ;调用getaddr函数获取exitprocess函数地址.
  79. call eax                            ;调用exitprocess
  80. ;------------------------B.j.H's split-line-----------------------------------
  81. ;下面这个才是重点!(个人认为)
  82. ;写一个根据dll的基地址查找API函数入口 的函数方便调用
  83. ;函数说明:此函数包括两个传入参数,一个是基地址,另一个是需要查询的函数名字符串首地址
  84. ;------------------------B.j.H's split-line-----------------------------------
  85. getapi:
  86. mov ebx,eax                                  ;eax存放的传入的基地址
  87. add eax,03ch                                 ;定位PE头位置地址
  88. mov eax,dword ptr [eax]               ;获得PE头偏移地址
  89. add eax,ebx                                   ;计算PE头VA
  90. cmp dword ptr [eax],00004550h    ;验证PE文件的合法性
  91. jne Err                                            ;不合法跳转
  92. mov eax,dword ptr [eax+078h]     ;导出表地址获得
  93. add eax,ebx                                  ;计算导出表入口VA
  94. push eax                                       ;保存导出表入口VA
  95. mov ecx,eax                                  ;令ecx指向导出表
  96. mov ecx,dword ptr [ecx + 014h]   ;找出导出表中函数个数作为循环值
  97. mov eax,dword ptr [eax + 020h]   ;找出函数名字符串地址表的偏移
  98. add eax,ebx                                  ;计算函数名字符串地址表的VA
  99. push ebp                                        ;保存ebp寄存器,寄存器不够用,借用一下,呵呵!
  100. mov ebp,eax                                  ;ebp保存函数名字符串地址表的VA
  101. xor edx,edx                                   ;edx清0用于存放函数索引
  102. LoopFind:
  103. push ecx;                                       ;保存ecx 循环次数
  104. mov eax,dword ptr[eax]                ;获取函数名字符串偏移
  105. add eax,ebx                                  ;计算函数字符串VA
  106. mov edi,eax                                   ;把VA赋值给edi 准备比较
  107. mov esi,dword ptr [esp + 014h]   ;这个地方要算好了!函数内部有3个push,每个push为4个字节一个12个字节
  108.                                                       ;字符串地址放在call外部倒数第二个push(这个自己用控制好第几个参数是自己定的)
  109.                ;也就是说从push 字符串地址到这个命令行之间有16个字节被push进入栈中。是不是就是+10H呢
  110.                ;注意我们这里用了一个函数,不是jmp,函数调用的时候会有一个push eip用于返回!
  111.                ;所以我们在计算的时候这个push不能忘,最后计算得到esp+14h中所放的就我们要查的函数名字符的地址
  112. mov ecx,dword ptr [esp + 010h]     ; 计算同上,这里是给ecx赋值,函数名的长度。ecx被改变了
  113.                                                         ;(后面,在loop命令之前要恢复的ecx,这个是计数器,硬性规定,呵呵!)
  114. cld                              ;
  115. repz cmpsb                                     ;字符串比较 esi 和 edi 比较
  116. jne FindNext                                   ;比较,如果不是,则取下一个函数
  117. add esp,4                                     ;找到往下执行 相当与pop ecx。无关紧要了!
  118. mov eax,dword ptr [esp + 04h]    ;恢复导出函数表入口
  119. mov eax,dword ptr [eax + 01ch]   ;获得函数地址表入口偏移
  120.                                                      ;我在这里缺少了一步,大多数情况不会有影响,具体的是哪一步,
  121.                                                      ;深究的同志可以看看关于函数导出表的函数查询方式
  122. add eax,ebx                      ;计算函数地址表入口VA
  123. shl edx,2                        ;函数索引*函数地址(默认为4个字节) 鉴戒别人的,很妙的一招相当与乘以4
  124. add eax,edx                      ;函数地址表基址+(函数索引)
  125. mov eax,dword ptr[eax]           ;获得函数入口地址偏移
  126. add eax,ebx                      ;计算VA
  127. jmp Found
  128. FindNext:
  129. inc edx                                ;计数器加一
  130. add ebp,4h                         ;函数名字符串地址表的VA指向下一个函数名地址
  131. mov eax,ebp                       ; 函数名地址的VA赋值到eax
  132. pop ecx                              ;恢复ecx 循环次数
  133. loop LoopFind                     ;loop 继续循环查找
  134. Err:
  135. xor eax,eax                       ;没有找到,或者出错,eax清理。
  136. Found:
  137. pop ebp                              ;恢复ebp
  138. pop ecx                               ;不能再恢复eax了!弹到ecx好了!
  139. ret 4                                    ; 返回 且 add esp 4
  140.                                            ;这个是因为我们调用完函数时需要利用之前我们自己建立函数名字符表。
  141. end start

复制代码


EXE编译大小为1K

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-8-6 09:30:47 | 显示全部楼层
汇编.....确实NB,很小很小......
我就是嗷嗷叫的老马了......

2

主题

12

回帖

0

精华

初来乍到

积分
27
发表于 2010-8-6 10:33:26 | 显示全部楼层
这个问题不是简单的问题,值得研究!!
cf聊天室5.5中文版 www.xsdownload.info

6

主题

32

回帖

2

精华

核心会员

积分
2250
发表于 2010-8-6 13:33:17 | 显示全部楼层
名不副实

28

主题

116

回帖

0

精华

铜牌会员

积分
273
发表于 2011-12-26 12:30:05 | 显示全部楼层
顶了!!!!
头像被屏蔽

0

主题

29

回帖

0

精华

金牌会员

积分
976
发表于 2014-3-29 00:23:34 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

68

回帖

0

精华

铜牌会员

积分
94
发表于 2015-1-10 21:33:16 | 显示全部楼层
学习了谢谢分享

30

主题

693

回帖

0

精华

钻石会员

积分
2815
发表于 2015-4-29 09:35:12 | 显示全部楼层
代码不错必须支持
影月邪歌 该用户已被删除
发表于 2017-10-13 11:09:45 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表