首页
社区
课程
招聘
[原创]MASM之ShellCode框架编写[合并帖]
发表于: 2011-6-7 21:17 12439

[原创]MASM之ShellCode框架编写[合并帖]

2011-6-7 21:17
12439
编写ShellCode前首先要做的是确定获取kernel32基地址的方法,在如今WIN7插手的年代,不得不抛弃以前在XP下通用的获取kernel32基地址的方法,而选择能同时在WIN7下运行的代码,参考文章:http://skypher.com/wiki/index.php/Hacking/Shellcode/kernel32,我们就拥有了兼容WIN7的代码了:(代码中寄存器改了下,所以和链接中的原文不一样了,不要奇怪哦)

	 assume fs:nothing
	 xor	ecx,ecx
    mov	esi,fs:[030H]							; ESI = &(PEB) ([FS:0x30])
    mov	esi,[esi+0cH]			            ; ESI = PEB->Ldr
    mov	esi,[esi+01cH]			            ; ESI = PEB->Ldr.InInitOrder
next_module:
    mov	eax,[esi+08H]			            ; eax = InInitOrder[X].base_address
    mov	edi,[esi+020H]		 	            ; eax = InInitOrder[X].module_name (unicode)
    mov	esi,[esi]           			      ; ESI = InInitOrder[X].flink (next module)
    cmp	[edi+12*2],cl        		      ; modulename[12] == 0 ?
    JNE     next_module                   ; No: try next module.


该代码执行之后,EAX会被设置成kernel32的基地址,之后就是动态获取API的方法了,可以自己实现GetProcAddress,也可以直接调用GetProcAddress,这里我偷下懒,直接调用原来的GetProcAddress
 

   mov	esi,eax
    mov	edi,30	
    assume eax:ptr IMAGE_DOS_HEADER
    mov	ecx,DWORD ptr [eax+edi*2]											; 03cH .e_lfanew,用了点迷惑作用
    lea	eax,[eax+ecx+2]
    assume	eax:ptr IMAGE_NT_HEADERS
    add	edi,078H-2-30
    mov	ecx,DWORD ptr [eax+edi]						; 078H .OptionalHeader.DataDirectory.VirtualAddress,用了点迷惑作用
    .if	ecx
     add	ecx,esi
     assume ecx:ptr IMAGE_EXPORT_DIRECTORY
     mov	ebx,cGetProcAddress
     sub	ebx,[ecx].nBase
     shl	ebx,2
     add	ebx,[ecx].AddressOfFunctions
     add	ebx,esi
     mov	ebx,[ebx]
     ;dec	ebx										;API地址故意减去1,让OD无法显示API名称
     add	ebx,esi									;ebx = "GetProcAddress" address
     mov	dGetProcAddress,ebx
     @fcall ebx,esi,cLoadLibraryA
     ;dec	eax										;API地址故意减去1,让OD无法显示API名称
     mov	dLoadLibraryA,eax
     @fcall ebx,esi,cGetModuleHandleA
     ;dec	eax										;API地址故意减去1,让OD无法显示API名称
     mov	dGetModuleHandleA,eax


之后要考虑到是问题是,如果插入字符串,在SHELLCODE中字符串只能插入到CODE中了,但也有几种插入的方法,这里说下我常用的方法:


CALL @F
db "这里是字符串",0
pop ...



但如果代码中插入大量这样的代码,不仅操作麻烦,还影响阅读,所以直接用一个宏来解决,如下:


settext macro arg,text:VARARG
	local @name
	call	@F
		@name:
		db text,0
	@@:
	ifnb <arg>
	pop	arg
	endif
endm


有了这几样之后,编写SHELLCODE基本上不成问题了,下面就来编写一个弹出信息框的例子:

		settext	szMsgName,"MessageBoxA"
		settext	szMsg,"SHELLCODE测试信息框"
		settext	szDllName,"user32"
		;下面要用到GetProcAddress & LoadLibraryA & GetModuleHandleA 组合来获取API函数MessageBoxA,并弹出一个信息框
		@fcall dGetModuleHandleA,szDllName
		.if	!eax
			@fcall dLoadLibraryA,szDllName
		.endif	
		.if	eax
			mov	hDLL,eax
			@fcall dGetProcAddress,hDLL,szMsgName
			.if	eax
				@fcall eax,0,szMsg,0,0		;弹出一个信息框
			.endif	
		.endif	
    .endif


可能你会说,每次这样调用太麻烦了,的确,所以建议大家可以建一张表,把要载入的API事先都读取好,之后只要用索引或者常量就可以调用了!如果下次有机会的话,我再写一份代码

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

收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
2
补上源代码:

frame1.rar

bin.rar

注意:本来以为API的序号导出换了系统还是一样的,现在才知道是不一样的,所以在其他系统上运行才会出错,额额,看来还是要改改了!!
上传的附件:
2011-6-7 21:20
0
雪    币: 80
活跃值: (45)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
2011-6-7 21:41
0
雪    币: 156
活跃值: (27)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
这个要支持下.........
2011-6-7 21:48
0
雪    币: 10026
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

mov ebx,[ebx]
;dec ebx ;API地址故意减去1,让OD无法显示API名称
add ebx,esi ;ebx = "GetProcAddress" address
mov dGetProcAddress,ebx

减1,汗,跟那个飘雪解密后的shellcode
分析的时候真想吐。。
2011-6-7 22:15
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
6
额,这个方法不好吗?有什么高招不....
2011-6-7 22:22
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
7
学习~~
2011-6-8 09:04
0
雪    币: 163
活跃值: (75)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
  win7的时代来临了....
2011-6-8 09:31
0
雪    币: 1452
活跃值: (2847)
能力值: ( LV9,RANK:156 )
在线值:
发帖
回帖
粉丝
9
学习      .
2011-6-8 10:47
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
10
与之前写的不同在于(http://bbs.pediy.com/showthread.php?t=135062),这次都用了宏来做框架,调用API也是非常方便了,不废话,直接看代码


.386
.model flat, stdcall
option casemap :none

include windows.inc
include myMacro.asm
.CODE
START proc 
local APIArrayBuff[2]:DWORD 	;设置一个API缓冲区,只要设置API总数就足够了

local chBuf[128]:BYTE ,dwRet
pushad
mov	dwRet,128

		;********************************************************************
		; SHELLCODE 新构架 设置导入表,注意,这里都不用双引号
			Import user32,MessageBoxA
			Import Advapi32,GetUserNameA
		; LdrImport的功能是将所有API装载到目标地址 APIArrayBuff则为API存放地址
		;调用的时候 只需要 APIArrayBuff[cMessageBoxA] 就可以访问到API地址 
		;也可以直接用ImportApiCall cMessageBoxA 的方式直接调用
		;cMessageBoxA 常量是自动生成的,是由"c" + API名称组成
			LdrImport APIArrayBuff
		;********************************************************************
		
		
;下面是两种调用方式 ImportApiCall 和 InlineCall 
;区别是:ImportApiCall需要调用Import 和LdrImport 之后才能使用,他可以直接用API内部常量来调用API
;而InlineCall可以直接使用,但不可以直接用API内部常量来调用API
		
ImportApiCall cGetUserNameA,addr chBuf,addr dwRet	;获取当前用户名


ImportApiCall cMessageBoxA,0,addr chBuf,"ImportApiCall:",48

InlineCall APIArrayBuff[cMessageBoxA],0,addr chBuf,"InlineCall:",16

popad
ret
START endp	
end START



编译后得出代码:
55 8B EC 81 C4 74 FF FF FF 60 C7 85 74 FF FF FF 80 00 00 00 60 83 EC 10 83 64 24 0C 00 33 C9 64
8B 35 30 00 00 00 8B 76 0C 8B 76 1C 8B 46 08 8B 7E 20 8B 36 38 4F 18 75 F3 8B F0 BF 1E 00 00 00
8B 0C 78 8D 44 01 02 83 C7 58 8B 0C 07 0B C9 74 34 03 CE BB 99 01 00 00 2B 59 10 C1 E3 02 03 59
1C 03 DE 8B 1B 4B 03 DE 89 1C 24 68 45 02 00 00 56 FF D3 48 89 44 24 04 68 77 01 00 00 56 FF D3
48 89 44 24 08 E8 12 00 00 00 75 73 65 72 33 32 00 01 41 64 76 61 70 69 33 32 00 01 5E E8 19 00
00 00 4D 65 73 73 61 67 65 42 6F 78 41 00 47 65 74 55 73 65 72 4E 61 6D 65 41 00 5F B9 02 00 00
00 EB 4E 51 56 FF 54 24 10 0B C0 75 05 56 FF 54 24 0C 0B C0 74 39 8B D8 56 E8 3D 00 00 00 8D 74
30 02 0F B6 4E FF EB 23 51 57 53 FF 54 24 10 0B C0 74 0C 8B 4C 24 14 89 44 8D F8 FF 44 24 14 57
E8 16 00 00 00 8D 7C 38 01 59 49 0B C9 75 D9 59 49 0B C9 75 AE 83 C4 10 61 EB 17 57 8B 7C 24 08
B9 FF FF FF FF 33 C0 F2 AE F7 D1 49 8B C1 5F C2 04 00 8D 85 74 FF FF FF 50 8D 85 78 FF FF FF 50
FF 55 FC 6A 30 E8 0F 00 00 00 49 6D 70 6F 72 74 41 70 69 43 61 6C 6C 3A 00 8D 85 78 FF FF FF 50
6A 00 FF 55 F8 6A 10 E8 0C 00 00 00 49 6E 6C 69 6E 65 43 61 6C 6C 3A 00 8D 85 78 FF FF FF 50 6A
00 FF 55 F8 61 C9 C3




易语言版:



.版本 2

置入代码 ({ 85, 139, 236, 129, 196, 116, 255, 255, 255, 96, 199, 133, 116, 255, 255, 255, 128, 0, 0, 0, 96, 131, 236, 16, 131, 100, 36, 12, 0, 51, 201, 100, 139, 53, 48, 0, 0, 0, 139, 118, 12, 139, 118, 28, 139, 70, 8, 139, 126, 32, 139, 54, 56, 79, 24, 117, 243, 139, 240, 191, 30, 0, 0, 0, 139, 12, 120, 141, 68, 1, 2, 131, 199, 88, 139, 12, 7, 11, 201, 116, 52, 3, 206, 187, 153, 1, 0, 0, 43, 89, 16, 193, 227, 2, 3, 89, 28, 3, 222, 139, 27, 75, 3, 222, 137, 28, 36, 104, 69, 2, 0, 0, 86, 255, 211, 72, 137, 68, 36, 4, 104, 119, 1, 0, 0, 86, 255, 211, 72, 137, 68, 36, 8, 232, 18, 0, 0, 0, 117, 115, 101, 114, 51, 50, 0, 1, 65, 100, 118, 97, 112, 105, 51, 50, 0, 1, 94, 232, 25, 0, 0, 0, 77, 101, 115, 115, 97, 103, 101, 66, 111, 120, 65, 0, 71, 101, 116, 85, 115, 101, 114, 78, 97, 109, 101, 65, 0, 95, 185, 2, 0, 0, 0, 235, 78, 81, 86, 255, 84, 36, 16, 11, 192, 117, 5, 86, 255, 84, 36, 12, 11, 192, 116, 57, 139, 216, 86, 232, 61, 0, 0, 0, 141, 116, 48, 2, 15, 182, 78, 255, 235, 35, 81, 87, 83, 255, 84, 36, 16, 11, 192, 116, 12, 139, 76, 36, 20, 137, 68, 141, 248, 255, 68, 36, 20, 87, 232, 22, 0, 0, 0, 141, 124, 56, 1, 89, 73, 11, 201, 117, 217, 89, 73, 11, 201, 117, 174, 131, 196, 16, 97, 235, 23, 87, 139, 124, 36, 8, 185, 255, 255, 255, 255, 51, 192, 242, 174, 247, 209, 73, 139, 193, 95, 194, 4, 0, 141, 133, 116, 255, 255, 255, 80, 141, 133, 120, 255, 255, 255, 80, 255, 85, 252, 106, 48, 232, 15, 0, 0, 0, 73, 109, 112, 111, 114, 116, 65, 112, 105, 67, 97, 108, 108, 58, 0, 141, 133, 120, 255, 255, 255, 80, 106, 0, 255, 85, 248, 106, 16, 232, 12, 0, 0, 0, 73, 110, 108, 105, 110, 101, 67, 97, 108, 108, 58, 0, 141, 133, 120, 255, 255, 255, 80, 106, 0, 255, 85, 248, 97, 201, 195 })




ps:感谢 Mr.Crowley 的帮忙~
上传的附件:
2011-6-9 14:37
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
11
碰过场了。。。
2011-6-9 14:45
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
12
ps:Import 语法是 第一个是库名称,后面跟API名称,不要分开写,都不用引号,要一次写完
如:

Import user32,MessageBoxA,SendMessageA,LoadIconA,GetWindowTextLengthA

Import kernel32,UnmapViewOfFile,RtlZeroMemory,MapViewOfFile
2011-6-9 15:00
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
13
将楼主的两个主题贴合并成一个,方便管理。
2011-6-9 19:08
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
14
谢谢
2011-6-9 19:21
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
15
顶起,谢谢!
2011-6-9 20:55
0
雪    币: 190
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
顶起,谢谢!
2011-6-10 14:41
0
雪    币: 129
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
学习了  呵呵
2011-6-10 15:12
0
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
18
win7 test error
2011-6-10 15:38
0
雪    币: 62
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
= =!雪花群看到你的帖子。。原来是大牛。。。期待你更好的作品!
2011-6-12 10:38
0
雪    币: 238
活跃值: (178)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
我测试也error啊,2003也不能用.
2011-6-13 16:18
0
游客
登录 | 注册 方可回帖
返回
//