首页
社区
课程
招聘
[原创]asm的魅力(四)
发表于: 2009-11-15 10:49 13976

[原创]asm的魅力(四)

2009-11-15 10:49
13976
Asm的魅力(四)
Asm是业界利器-----------------------某人

Date:2009.11.15
Author:charme
Index:http://hi.baidu.com/charme000
Email:charme000@gmail.com

        很久没有研究技术的东西了,心静不下来。现在稍微好点了,接着以前的主题,希望大家不要厌烦,呼呼!!

        为什么说asm是业界利器呢?实际上搞破解和逆向分析的人体会最深了。我以前并不研究什么破解啊什么
的,主要是没兴趣,有时候倒是也逆向一些东西!最近稍微的接触了下,觉得挺有意思的,也不是那么难!但是说到底吧,这里面最根本的实际上还是asm的功底和一些调试技巧!希望不久可以写个拙略的破文出来。
在此特别感谢下啊cr和zapline的帮助。

        最近写了篇关于inline hook的整体架构的东西,放空间了(严重鄙视百度的日志篇幅限制,害我分了7篇,丫的!)。师傅说不喜欢看asm,我也没有办法,很俗的说:习惯了,呼呼!

        很多人问我:为什么要叫“asm魅力“。呼呼,因为我的名字叫charme(英文意思:魅力)。

        昨天一个朋友问我:asm可以写驱动么?当然可以!!!!!

        那么这篇呢我们就以这个为主题,我实现一个简单的驱动出来。

原理:
我们简单的自己实现一个调用门,来查询r0状态是一些寄存器的值!

驱动部分------------------------------------------------------------------------------------------------

;名称:MyKmd.asm

;功能:一个很简单的WDM(KDM)驱动程序,为自己的程序提供Ring0。

;说明:需要由“LoadMyKmd.exe”来安装。


;>>>>>>>>>>>>>>>STRUCT>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CALLGATE	STRUCT
	OFFSETL		DW	0
	SELECTOR	DW	0
	DCOUNT		DB	0
	GTYPE		DB	0
	OFFSETH		DW	0
CALLGATE    ENDS

DESCRIPTOR  STRUCT
	LIMITL		DW	0
	BASEL		DW	0
	BASEM		DB	0
	ATTRIBUTES	DW	0
	BASEH		DB	0
DESCRIPTOR  ENDS
;>>>>>>>>>>>>>>>>>equ>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CODES_SEL  =  3E8H
CODE_TYPE  =  0CF9AH
GATE_TYPE  =  0ECH

;>>>>>>>>>>>>>>>>>Code>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
  DriverEntry:
	pushfd
	pushad

	;取得GDTR内容
	push	edx			;压栈edx,esp-4,构建4字节空间
	sgdt	[esp-2]			;GDTR是48位,这里利用了技巧,在栈中构建了6字节空间,同时读出GDTR内容
					;而且还不破坏堆栈指针,巧巧巧!
	pop	edx			;全局描述符表基地址——这里只关心基址(在高双字,高址),所以出栈即是
	mov	eax,edx			;存放全局描述符开始地址

	;在全句描述符表开始地址存放retn指令机器码, 全句描述符表第一个描述符为空
	;表述符,被保留,没被用书上说这个描述符应该全为0这里看出 可以写东西进去。
	mov	BYTE ptr [edx],0C3H 

	mov	ecx,3E0h		;定位自己的门描述符,
	add	edx,ecx			;

     assume edx:ptr CALLGATE		;让描述符符位置在全局描述符的3E0这个位置
	cmp	[edx].SELECTOR,CODES_SEL
	jz	_ToEnd

	mov	[edx].OFFSETL,ax	;创建门描述符
	mov	[edx].SELECTOR,CODES_SEL
	mov	[edx].DCOUNT,0
	mov	[edx].GTYPE,GATE_TYPE
	shr	eax,16
	mov	[edx].OFFSETH,ax
	;描述符的偏移地址其实就是上面说到的那个retn指令地址,当call 这个门的时候
	;只从堆栈弹出EIP地址,所以CS寄存器没被覆盖,所以还是ring0权限

	add	edx,8
     assume edx:ptr DESCRIPTOR
	mov	[edx].LIMITL,0FFFFH	;创建自己的代码段描述符
	mov	[edx].BASEL,0
	mov	[edx].BASEM,0
	mov	[edx].ATTRIBUTES,CODE_TYPE
	mov	[edx].BASEH,0
  _ToEnd:
	popad
	popfd
	mov	eax,0C0000182h
	ret	8 
end DriverEntry

说明:
这个源文件实际上可以写成一个MyKmd.bat文件,对于其中的批处理,编译的时候按注释处理,忽略。这是一种很好的处理方法。或者你也可以单独的写个bat文件来编译!代码中作了详细的注释。一看就明白!
这其中几处巧妙的地方正是asm得魅力所在,希望大家能够真正的体会出来!

Loader-------------------------------------------------------------------------------
我们也可以写个加载驱动的loader!这里只是演示,就不涉及什么xx的东西了,用最普通的方法来加载。

;名称:LoadMyKmd.asm

;功能:安装驱动程序“MyKmd.sys”使用。

;说明:必须生成“MyKmd.sys”之后才能正确运行。

;编译方式——见程序尾部


.data
	szError		db	'装载驱动失败',0
	szOK1		db	'驱动安装成功',0
	szOK		db	'OH YEAH.~~!',0
	szMyWdm		db	'MyKmd.sys',0
	szMyWdnName	db	'MyKmd',0
	szBuffer	db	MAX_PATH dup (0)

	hSCManager	dd	?
	hService	dd	?

.code
 start:
	invoke	OpenSCManager,NULL,NULL,SC_MANAGER_CREATE_SERVICE
	.if !eax
		invoke	MessageBox,0,addr szError,0,MB_ICONERROR or MB_OK
		jmp _Err
	.endif
	mov hSCManager,eax
	push ecx
	invoke  GetFullPathName,addr szMyWdm,sizeof szBuffer,addr szBuffer,esp
	pop ecx
	invoke  CreateService,hSCManager,addr szMyWdnName,addr szMyWdm, \
			SERVICE_START or DELETE,SERVICE_KERNEL_DRIVER, \
			SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE, \
			addr szBuffer,0,0,0,0,0
	.if !eax
		invoke  MessageBox,0,addr szError,0,MB_ICONERROR
		jmp _Err
	.endif
	mov hService,eax
	invoke  StartService, hService, 0, NULL
	invoke  DeleteService, hService
	invoke  CloseServiceHandle, hService
	invoke  CloseServiceHandle, hSCManager
	invoke  MessageBox,0,addr szOK1,addr szOK,0
 _Err:
	invoke  ExitProcess,0
	end start

说明:写过驱动的人应该对这些基本的函数都很熟悉的!

现在的话,驱动文件和loader都有了。我们再写个测试程序出来!看看到底能不能出来我们想要的效果!

Test部分:
;程序名:Mytest.asm

;功能:用来测试MyKmd.sys是否正确


.data
	szOK		db	'Test Ring0',0
	CallGate_Sel	dd	0
			dw	03E3H		;调用门的选择子
	szFormat	db	'通用寄存器:',0Dh,0Ah
			db	'EAX=%08X   EBX=%08X   ECX=%08X   EDX=%08X',0Dh,0Ah
			db	'ESI=%08X   EDI=%08X   EBP=%08X   ESP=%08X',0Dh,0Ah,0Dh,0Ah
			db	'段(选择符)寄存器:',0Dh,0Ah
			db	' CS=%04X   DS=%04X  ES=%04X   SS=%04X   FS=%04X  GS==%04X',0Dh,0Ah,0Dh,0Ah
			db	'指令指针寄存器:EIP=%08X  标志寄存器:EFLAGS=%08X',0Dh,0Ah,0Dh,0Ah
			db	'控制寄存器:',0Dh,0Ah
			db	' CR0=%08X   CR1:CPU保留   CR2=%08X   CR3=%08X',0Dh,0Ah,0Dh,0Ah
			db	'系统地址寄存器:',0Dh,0Ah
			db	' GDTR=%04X %08X  IDTR=%04X %08X TR=%04X LDTR=%04X',0Dh,0Ah,0Dh,0Ah
			db	'调试寄存器:',0Dh,0Ah
			db	' DR0=%08X  DR1=%08X   DR2=%08X   DR3=%08X',0Dh,0Ah
			db	' DR4:CPU保留  DR5:CPU保留   DR6=%08X   DR7=%08X',0,0
.data?
	szBuffer	db	500h dup (?)
	_ddEAX		dd	?
	_ddEBX		dd	?
	_ddECX		dd	?
	_ddEDX		dd	?
	_ddESI		dd	?
	_ddEDI		dd	?
	_ddEBP		dd	?
	_ddESP		dd	?
	_ddCS		dd	?
	_ddDS		dd	?
	_ddES		dd	?
	_ddSS		dd	?
	_ddFS		dd	?
	_ddGS		dd	?
	_ddEIP		dd	?
	_ddEFLAGS	dd	?
	_ddCR0		dd	?
	;_ddCR1		dd	00000000h	;CPU保留
	_ddCR2		dd	?
	_ddCR3		dd	?
	_dfGDTR		dd	?		;低16位是界限
			dd	?
	_dfIDTR		dd	?
			dd	?
	_ddTR		dd	?
	_ddLDTR		dd	?
	_ddDR0		dd	?
	_ddDR1		dd	?
	_ddDR2		dd	?
	_ddDR3		dd	?
	;_ddDR4		dd	00000000h	;CPU保留
	;_ddDR5		dd	00000000h	;CPU保留
	_ddDR6		dd	?
	_ddDR7		dd	?

.code
start:
	call	FWORD ptr CallGate_Sel

	;进入ring0
	;有兴趣自己也可以创建一个0级堆栈,这里用ring3的堆栈
	mov	eax,esp				;保存ring0堆栈
	mov	esp,[esp+4]			;装入ring3堆栈地址
	;解释下这里为什么是+4:  因为call调用门会把ss esp cs eip分别放入堆栈,在驱动
	;程序里面已经有一句ret 8指令把eip弹出来了。所以这里就得加4以得到ring3堆栈地址
    
	push	eax

	mov	_ddEAX,eax
	mov	_ddEBX,ebx
	mov	_ddECX,ecx
	mov	_ddEDX,edx
	mov	_ddESI,esi
	mov	_ddEDI,edi
	mov	_ddEBP,ebp
	mov	_ddESP,esp
	mov	_ddCS,DWORD PTR cs
	mov	_ddDS,DWORD PTR ds
	mov	_ddES,DWORD PTR es
	mov	_ddES,DWORD PTR ss
	mov	_ddFS,DWORD PTR fs
	mov	_ddGS,DWORD PTR gs
	push	eax
	pop	_ddEIP
	pushfd	
	pop	_ddEFLAGS
	mov	eax,cr0
	mov	_ddCR0,eax
	mov	eax,cr2
	mov	_ddCR2,eax
	mov	eax,cr3
	mov	_ddCR3,eax
	sgdt	FWORD PTR _dfGDTR
	sidt	FWORD PTR _dfIDTR
	xor	eax,eax
	str	ax
	mov	_ddTR,eax
	xor	eax,eax
	sldt	ax
	mov	_ddLDTR,eax
	mov	eax,dr0
	mov	_ddDR0,eax
	mov	eax,dr1
	mov	_ddDR1,eax
	mov	eax,dr2
	mov	_ddDR2,eax
	mov	eax,dr3
	mov	_ddDR3,eax
	mov	eax,dr6
	mov	_ddDR6,eax
	mov	eax,dr7
	mov	_ddDR7,eax			;ring0下才可以访问的寄存器

	pop	esp

	;;;开发返回ring3
	push	offset ring3

	;正如刚刚所说,已经弹出了eip地址。
	;用retf返回肯定出错。所以还是手动帮忙来恢复堆栈,压入ring3下的代码地址
	retf
ring3:
	mov	eax,_dfGDTR
	mov	ebx,_dfGDTR+4
	xchg	ax,bx
	rol	eax,16
	mov	_dfGDTR,eax
	mov	_dfGDTR+4,ebx
	mov	eax,_dfIDTR
	mov	ebx,_dfIDTR+4
	xchg	ax,bx
	rol	eax,16
	mov	_dfIDTR,eax
	mov	_dfIDTR+4,ebx

	invoke	wsprintf,addr szBuffer,addr szFormat,\
		_ddEAX,_ddEBX,_ddECX,_ddEDX,\
		_ddESI,_ddEDI,_ddEBP,_ddESP,\
		_ddCS,_ddSS,_ddDS,_ddES,_ddFS,_ddGS,\
		_ddEIP,_ddEFLAGS,\
		_ddCR0,_ddCR2,_ddCR3,\
		_dfGDTR+4,_dfGDTR,_dfIDTR+4,_dfIDTR,_ddTR,_ddLDTR,\
		_ddDR0,_ddDR1,_ddDR2,_ddDR3,_ddDR6,_ddDR7
	invoke	MessageBox,0,addr szBuffer,addr szOK,0
	invoke	ExitProcess,0
end start
说明:也是很简单的!呼呼!

最终的效果图:

这篇陋文不是要教你怎么写个调用门什么的!要写这样的东西的话,看看combojiang(也不知道拼对了没有,呼呼)大牛的rootkits系列就可以了! 我的目的是想让大家体会下asm的魅力,仅此而已!比起N多大牛的内核驱动程序来说,这个就很简陋了,呼呼!不过现在好多的大牛都简陋的不会写简陋的东西了!

建议:
我个人是这么看的,我并不建议用asm来写驱动,除非你有足够的驾驭能力。
原因1-----asm本身很晦涩,即便他强大。Asm写驱动就有点像用mfc开发gui程序和.net开发gui程序的对比。前者可能在某些方面要强大一点,但是开发速度和效率没有后者强!这个看情况择优!
原因2-----asm写的驱动不好调试。最普遍的就是三精口服液 。

总结:
其实任何的语言无非是规则,高手在于能够充分的理解规则并且试图突破!
对于asm写驱动,前辈已经做了尝试,大家可以到小罗的主页上下载俄罗斯大牛整理的masm开发驱动的开发包KmdKit。相当于ddk一样的东西,很实用!

好了,asm魅力四写完了!就像又完成了一件事情一样!也很开心!
昨天受人委托去辅导一个高中生的去过信息竞赛,不禁感慨一番,里面设计很多的数据结构还有算法的问题,一个动态规划的问题,忙活了我两个小时才写出程序来。看来还是欠火候,希望小妹妹可以一切顺利,也不枉我一番教导啊!呼呼!

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (21)
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
2
支持,呼呼什么时候才出完,整理成电子书?
2009-11-15 10:52
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
3
我都不知道会出到是么时候,呼呼
2009-11-15 10:55
0
雪    币: 232
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
可以整理个专题了..呵呵
2009-11-15 11:12
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
5
这个不是核做专题,,就是想起来 时候瞎写一篇,,呼呼,,也没有多少人爱看这样的东西
2009-11-15 20:53
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
哈哈 顶一下
2009-11-15 21:01
0
雪    币: 227
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我倒是不觉得,只是很多人想看但是又找不到。
我就是其中的一个了。
希望能看到更多。
2009-11-15 22:04
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
楼主又来了,顶~ zapline帮了什么忙?不会是倒忙吧?嘿嘿
2009-11-15 22:21
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
9
那我尽量努力吧
2009-11-16 08:40
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
10
不错 支持下
2009-11-16 12:38
0
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
11
感谢楼主。
6个字。
2009-11-17 11:35
0
雪    币: 270
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
12
charme的asm功力太强了,看了半天,最后还是好读书不求甚解吧
2009-11-17 17:10
0
雪    币: 420
活跃值: (77)
能力值: ( LV13,RANK:500 )
在线值:
发帖
回帖
粉丝
13
小狼。。。
2009-11-17 17:45
0
雪    币: 202
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
MARK .哎。学学。哎。~都是驱动的了。
2009-11-18 21:23
0
雪    币: 219
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
好文章! 学习  谢谢楼主
2009-11-18 21:55
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
不错,很有体会,学习...
2009-11-19 12:46
0
雪    币: 166
活跃值: (79)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
17
帮小弟顶一下。
加油!
2009-11-27 13:55
0
雪    币: 433
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
18
support
2009-11-27 14:16
0
雪    币: 1753
活跃值: (840)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
19
KMD写的驱动~~~真是高手`~
偶工作还是用C写设备驱动~`
2009-12-5 16:06
0
雪    币: 112
活跃值: (48)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
20
你雷到我了,,呼呼,,你这个职位很特别啊,,密码学 见习 数学 理论  这么多名词,,很特别啊,,呼呼,,有意思
2009-12-5 16:51
0
雪    币: 247
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
标记学习了啊!
2010-8-20 23:17
0
雪    币: 991
活跃值: (195)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
http://bbs.pediy.com/showthread.php?t=59005
2010-11-13 12:37
0
游客
登录 | 注册 方可回帖
返回
//