能力值:
( LV12,RANK:300 )
|
-
-
26 楼
其实我主要并不是在强调这个“主线程”的严密概念,也许你误以为我是故意强调这个“主”字,是我表述不严密。
我的意思是一般进入shellcode的一开始不是在线程初始化的环境,这和修改入口点的感染型病毒的环境不一样,shellcode的环境通常更具有随机性,因此一般不用这个方法。这才是我的回帖想强调的内容,即这个环境的差异。这里我表述的“主线程”,我其实想指的是进入shellcode时的那个线程环境,这当然不一定是进程的主线程,只是对于shellcode来说(这里可能有点“拟人”了,即shellcode它“置身”的那个环境),即是它原始“生命力”所依赖的环境,这与对于病毒而言的主线程有相似的地位,因此我随口用了“主线程”这个词,其实是shellcode自身意义上的“主线程”,这样的借用,应该比罗罗嗦嗦说上一堆话来解释简明得多吧,当然容易引起误解。我相信这个应该可以意会的,没想到还是出现彼此误解,是我表述的问题。
好了,在这种情况下,这时shellcode它身处的这个环境一般不是处于线程刚刚初始化的状态。
这里我想说的其实是,就是在这种环境下,我假设它不用其他方法取得CreaeThread的地址的情况下,它在这个它所初始依赖的线程环境中,就难以“首先”用这个方法来获取kernel32.dll的基址。
所以,实际上就我想表达的意思来讲,你根本没有“反驳”我,也不必“反驳”我。
当然严格来说,的确如你所说,在shellcode中先通过其他方法获取CreateThread地址,然后创建一个新线程,这个新线程的确就可以使用这种方法再去获取kernel32.dll的地址。
因此我提“先有蛋还是先有鸡”并不是说“技术上不可行”,而是因为已经有了CreateThread地址就可以不用这样的方法,所以在shellcode实际中使用这种方法的可能性比较小,所以我说“一般不用”并不是“技术上不能用”,而是有所取舍的情况下,相比之下感染型病毒就比较常用这个方法,而shellcode中就比较少用。
shellcode中现在普遍还是使用PEB的方法比较多。
我提这个的原因还有一点,就是希望楼主这篇文章能够再加入比较一下这三个方法的讨论内容。
比如我以上说的话题就是一个讨论内容,不局限于病毒,对于相像的shellcode来说,获取kernel32.dll基址也是具有同等甚至更高的重要性。
为什么说“重要性可能更高”,是因为更“别无选择”。病毒其实也可以在感染时把原程序中指向LoadLibraryA和GetProcAddress的IAT位置保存下来,或者自己在输入表中加上相应项目,感染后的程序一旦运行,这个IAT已经被系统填上了地址,病毒直接用就行了,现实中有些病毒就是这么做的,这就跟壳差不多了。病毒一般就是依靠修改原PE程序而获得其代码执行机会,而shellcode没有这样的条件,包括一般不能像病毒这样用原始IAT来获得API地址,所以对于shellcode来说,动态获取kernel32.dll的地址就显得更为重要。
上面又提到了壳,壳又怎么样呢?病毒和壳也是比较像的,有的病毒可以说是用壳的方式感染文件。
因此以上这些内容,其实不是完全无关的,楼主在讲的虽然是AntiVirus,但其实本质上涉及到PEDIY的方方面面,因此有必要拓宽了讲,让大家有个整体全局上的了解。
|
能力值:
(RANK:510 )
|
-
-
27 楼
支持一下xfish的病毒分析系列教程。
病毒分析与防治也是逆向工程的重要应用,是一个很好的发展方向!
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
谢谢xfish, 看完后学到好多
我以前都是用这样的方法:以10000h为增量暴力搜索MZ标志 再定位到输出表的NAME字段
定位指定模块的基址
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
楼主讲的真不错,很详细,赞一个. 希望代码的注释再详细一点,虽然已经很简单了.
;///////////////////////////////////////
;++ 问题:这里的"++"和后面的"--",代表什么?
;
; int ;调用方式
; GetKrnlBase2(
; void
; )
;
; Routine Description: ;功能描述
;
; 获得kernel32基地址
;
; Arguments: ;传入参数
;
; (esp) - return address
;
;
; Return Value: ;返回值
;
; eax = krnl32 base
;--
;///////////////////////////////////////
|
能力值:
( LV2,RANK:10 )
|
-
-
30 楼
是作者都注释风格吧
|
能力值:
( LV9,RANK:220 )
|
-
-
31 楼
恩,我的注释风格,
;++ 代表开始位置
;-- 代表结束
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
这些都是进入kernel32.dll内部然后向上找到基址的,可以不进入其内部找到其基址么?
|
能力值:
( LV9,RANK:220 )
|
-
-
33 楼
第三种方法不就是吗。
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
搞错了,第三种确实是的!
|
能力值:
( LV2,RANK:140 )
|
-
-
35 楼
先顶后看~~~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
36 楼
楼主好强哦
学习。。。
|
能力值:
( LV3,RANK:20 )
|
-
-
37 楼
学习ing~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
分析过kernel32.dll的朋友应该都知道kernel32.dll的块对齐值是00001000h, 并且一般DLL以1M为边界,所以我们可以通过10000h (64k) 作为跨度,这样可以增加搜索速度。
只知道kernel32.dll的块对齐值是00001000h,一般DLL以1M为边界是什么意思,不明白,希望老大指点,然后又怎么得到64K为跨度呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
支持,写的很好啊
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
好文,就是最后一个看了一会儿才懂。原来_LIST_ENTRY是嵌入到结构体里面的,开始看了一会儿没懂~呵呵
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
1.加壳后呢?以及你并不知道病毒代码什么时候被执行到,那时的[ESP]不一定指向ExitThread()
2.擦除'MZ'和'PE'就能给你带来很大的麻烦,程序自己VirtualProtect()+WriteProcessMemory()一下就行,很简单。
3.或许这个是最好的方法了。。。。但是MS也没个准,说不定下次SP就给你改了。
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
真不错,学习了!
|
能力值:
( LV2,RANK:10 )
|
-
-
43 楼
膜拜.......
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
mov edx, [esp]
.Next:
dec edx ;
xor dx, dx ; 减去跨度
cmp word [edx], "MZ"
jz .IsPe
jmp .Next
.IsPe:
mov eax, [edx+3ch]
cmp word [eax+edx], 'PE'
jnz .Next
xchg eax, edx ; eax = kernel32 基地址
这段代码为什么要这样算
dec edx ;
xor dx, dx ; 减去跨度
为什么要 EDX 先自减一,然后再将 DX 清零
mov eax, [edx+3ch]
为什么要 EDX+3CH呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
45 楼
mov eax, [edx+3ch]
为什么要 EDX+3CH呢?
edx这时候就指向文件偏移0的地址,在3ch存放的就是PE文件头的地址.
dec edx ;假如edx=00030000h,dec edx 后就是0002FFFFh
xor dx, dx ; 减去跨度,xor dx,dx就是低四位清零,edx=00020000h
这两句代码就刚好减去00010000h.
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
用RADASM编译楼主的第 一种方法的代码,不行啊,,
会产生异常,,,,,,这是什么原因
|
能力值:
( LV2,RANK:10 )
|
-
-
47 楼
虽然不太看的懂,但我还是要看,学习,把它弄懂。
|
能力值:
( LV2,RANK:10 )
|
-
-
48 楼
.386
.model flat, stdcall
option casemap :none
include windows.inc
.code
start: mov edx, [esp]
Next: dec edx ;
xor dx,dx;
cmp word ptr [edx], 5A4Dh;
jnz Next;
IsPe:
mov eax, [edx+3ch];
cmp word ptr [eax+edx], 4550h;
jnz Next;
xchg eax,edx;
end start
我觉得楼主第一种方法的代码写错了,,,MZ十六制代码是4D5A,而内存读写会读写成5A4D,所以不能用"MZ"判断
|
能力值:
( LV2,RANK:10 )
|
-
-
49 楼
[QUOTE=hackerlx;630734].386
.model flat, stdcall
option casemap :none
include windows.inc
.code
start: mov edx, [esp]
Next: dec edx ;
xo...[/QUOTE]
楼上的,是你搞错了。再仔细想想在内存中的排布
|
能力值:
( LV2,RANK:10 )
|
-
-
50 楼
可我用OD跟过了,,,,
386
.model flat, stdcall
option casemap :none
include windows.inc
.code
start: mov edx, [esp]
Next: dec edx ;
xor dx,dx;
cmp word ptr [edx], 5A4Dh;
jnz Next;
IsPe:
mov eax, [edx+3ch];
cmp word ptr [eax+edx], 4550h;
jnz Next;
xchg eax,edx;
end start
这段代码是通过,,能得到基址,,用楼主的就不行,
|
|
|