首页
社区
课程
招聘
[求助]函数长度如何编程确定
发表于: 2009-12-28 09:31 7266

[求助]函数长度如何编程确定

2009-12-28 09:31
7266
例如得到一个函数入口

CALL 0x4XXXX

如何确定这个4XXXX地址的函数长度大小,可能有多个分支,多个retn?

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

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个....
2009-12-28 10:26
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
最省事的办法,保存call的目标地址,替换成自己的,在自己的过程中如果需要调用原函数,使用保存下来的地址便可.
2009-12-28 10:42
0
雪    币: 1556
活跃值: (310)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
啊哈 我知道你的意思 不过我要的比你想的还要YD点
2009-12-28 10:50
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
我不理解 YD的含义.
我觉得拷贝整个函数体是一件麻烦事,一般无此需要.
2009-12-28 11:35
0
雪    币: 4583
活跃值: (3567)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
6
动用反汇编引擎,进行数据流分析,以跳转指令为边界划分程序块,不跟进call指令中,以ret系列指令
为中止条件,进行深度优先遍历。你得自己写代码完成这件工作。一般来说,简单点,不考虑间接跳转
(比如跳转表、跳寄存器)。
2009-12-28 13:42
0
雪    币: 45
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
NOP+INT 3
2009-12-28 14:47
0
雪    币: 1556
活跃值: (310)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
8
嗯 我也这么想 但就是深度优先的策略没想明白

例如

JMP 地址A

一些CODE

JMP 地址B

假设地址A处往下就有一个RET,地址为C,而地址B可能在C之上也可能在C之下,那么怎样判断跳转为最深呢?

to morning

一般是无此需要 不过想弄些好玩的东西 3Q all the same
2009-12-30 10:51
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
9
0.单函数识别
从一个地址开始,在未知长度的情况下,识别出这个函数的长度。
流程算法如下:
1) 从当前位置开始进行反汇编
   2) 记录所有跳转流程指令
   3) 遇到ret或者retn指令后,回溯整个跳转流程链表
4) 如果找到jcc则判断是否跳转后的地址是否大于当前的指令地址
   5-1) 大于,则跳转到流程,进入预分析结尾流程
   5-2) 无大于的情况,此函数分析完毕,返回

我在论坛上发过。实际编码的测试效果也很不错。
2009-12-30 11:20
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
发个简单的。只能解析规则的代码。
GetProcSize	proc	uses esi ebx edi pProc:DWORD
;eax		指令长度
;ebx		跳转偏移量
;ecx		函数地址
;esi		分析指令地址
;edi		最远的指令地址

	mov		esi,pProc
	mov 	edi,esi
	
	invoke	GetCodeSize,esi
	.while	eax
		.if	eax == 2 && ( (byte ptr[esi] > 70H && byte ptr[esi] < 7FH) || byte ptr[esi] == 0EBH )
			movsx	ebx,byte ptr[esi+1]
		.elseif	eax == 5 && byte ptr[esi] == 0E9H
			mov 	ebx,[esi+1]
		.elseif eax == 6 && byte ptr[esi] == 0FH && byte ptr[esi+1] > 80H && byte ptr[esi+1] < 8FH
			mov 	ebx,[esi+2]
		.else
			.if	(byte ptr[esi] == 0C2H || byte ptr[esi] == 0C3H || byte ptr[esi] == 0CAH || byte ptr[esi] == 0CBH) && esi == edi
				lea 	eax,[esi+eax]
				sub		eax,pProc
				ret
			.else
				xor		ebx,ebx
			.endif
		.endif
		add		esi,eax
		test	ebx,ebx
		.if	!sign?
			add 	ebx,esi
			.if	ebx > edi
				mov 	edi,ebx
			.endif
		.endif
		.if	esi > edi
			mov 	edi,esi
		.endif
		invoke	GetCodeSize,esi
	.endw
	xor		eax,eax
	ret
GetProcSize endp
2009-12-30 11:21
0
雪    币: 1556
活跃值: (310)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
谢谢GStar

to 玩命:竟然没看到这篇更新 惭愧惭愧

期待新书~
2009-12-30 12:41
0
雪    币: 1556
活跃值: (310)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
12
BTW 上跳忽略没问题吗?

或者说 是否保证函数内部的代码均在函数入口以下?
2009-12-30 12:51
0
雪    币: 155
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
e...看来你没明白什么叫dfs了。。。跟地址高低没有关系 主要是看ret指令
2009-12-31 13:59
0
雪    币: 22
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
问的好,在头疼call里面是vmp的话,怎么找vm的出口地址。
2009-12-31 14:29
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
自己想在论坛搜索一下

我就看到过两个同样的帖子,玩命老大的理论算法都给出了
2009-12-31 19:50
0
雪    币: 242
活跃值: (418)
能力值: ( LV11,RANK:188 )
在线值:
发帖
回帖
粉丝
16
自己一般是在OD里写个脚本。
从call进入函数处开始保存个eip并进行判断,当esp再次操作到返回地址时停止并用当前eip减个保存的eip.
当然也可以自己写个简单的调试器挂 单步断点得到长度
2010-1-2 04:22
0
游客
登录 | 注册 方可回帖
返回
//