首页
社区
课程
招聘
[Anti Virus专题]1.2 - 2.kernel32基地址获得
2009-4-10 15:09 67601

[Anti Virus专题]1.2 - 2.kernel32基地址获得

2009-4-10 15:09
67601
收藏
点赞7
打赏
分享
最新回复 (86)
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
轩辕小聪 7 2009-4-11 20:01
26
0
其实我主要并不是在强调这个“主线程”的严密概念,也许你误以为我是故意强调这个“主”字,是我表述不严密。
我的意思是一般进入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的方方面面,因此有必要拓宽了讲,让大家有个整体全局上的了解。
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
加百力 12 2009-4-12 08:44
27
0
支持一下xfish的病毒分析系列教程。

病毒分析与防治也是逆向工程的重要应用,是一个很好的发展方向!
雪    币: 290
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
feifeixiao 2009-4-12 18:42
28
0
谢谢xfish, 看完后学到好多

我以前都是用这样的方法:以10000h为增量暴力搜索MZ标志  再定位到输出表的NAME字段
                        定位指定模块的基址
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
imaker 2009-4-13 21:00
29
0
楼主讲的真不错,很详细,赞一个.      希望代码的注释再详细一点,虽然已经很简单了.
;///////////////////////////////////////
;++                                                   问题:这里的"++"和后面的"--",代表什么?
;
; int                                                ;调用方式
;   GetKrnlBase2(
;    void
;   )
;
; Routine Description:                               ;功能描述
;
;    获得kernel32基地址
;
; Arguments:                                        ;传入参数
;
;    (esp)          - return address
;
;
; Return Value:                                     ;返回值
;
;    eax =  krnl32 base
;--
;///////////////////////////////////////
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zapline 2009-4-13 21:15
30
0
是作者都注释风格吧
雪    币: 315
活跃值: (23)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
xfish 5 2009-4-14 00:19
31
0
恩,我的注释风格,

;++ 代表开始位置

;-- 代表结束
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cham 2009-4-14 08:05
32
0
这些都是进入kernel32.dll内部然后向上找到基址的,可以不进入其内部找到其基址么?
雪    币: 315
活跃值: (23)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
xfish 5 2009-4-14 10:22
33
0
第三种方法不就是吗。
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cham 2009-4-14 11:08
34
0
搞错了,第三种确实是的!
雪    币: 101
活跃值: (88)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
nkspark 3 2009-4-14 11:14
35
0
先顶后看~~~~~
雪    币: 474
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
feierin 2009-4-15 13:53
36
0

楼主好强哦
学习。。。
雪    币: 124
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
zyfnhct 2009-4-17 13:14
37
0
学习ing~~~
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaodai 2009-4-18 20:32
38
0
分析过kernel32.dll的朋友应该都知道kernel32.dll的块对齐值是00001000h, 并且一般DLL以1M为边界,所以我们可以通过10000h (64k) 作为跨度,这样可以增加搜索速度。

      只知道kernel32.dll的块对齐值是00001000h,一般DLL以1M为边界是什么意思,不明白,希望老大指点,然后又怎么得到64K为跨度呢?
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hehuolong 2009-4-19 01:47
39
0
支持,写的很好啊
雪    币: 204
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
StarWing 2009-4-19 03:27
40
0
好文,就是最后一个看了一会儿才懂。原来_LIST_ENTRY是嵌入到结构体里面的,开始看了一会儿没懂~呵呵
雪    币: 152
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
XSJS 2009-4-19 10:57
41
0
1.加壳后呢?以及你并不知道病毒代码什么时候被执行到,那时的[ESP]不一定指向ExitThread()
2.擦除'MZ'和'PE'就能给你带来很大的麻烦,程序自己VirtualProtect()+WriteProcessMemory()一下就行,很简单。
3.或许这个是最好的方法了。。。。但是MS也没个准,说不定下次SP就给你改了。
雪    币: 104
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
刘国华 2009-4-26 19:40
42
0
真不错,学习了!
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
一转身 2009-4-29 21:53
43
0
膜拜.......
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
一转身 2009-5-14 14:00
44
0
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呢?
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hackerlx 2009-5-22 22:38
45
0
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.
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hackerlx 2009-5-23 18:34
46
0
用RADASM编译楼主的第 一种方法的代码,不行啊,,

会产生异常,,,,,,这是什么原因
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zousf 2009-5-25 14:29
47
0
虽然不太看的懂,但我还是要看,学习,把它弄懂。
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hackerlx 2009-5-25 18:25
48
0
.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"判断
雪    币: 104
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
刘国华 2009-5-26 08:14
49
0
[QUOTE=hackerlx;630734].386
                .model flat, stdcall
                option casemap :none   
                include        windows.inc
               
               

                .code
start:        mov  edx, [esp]
Next:          dec  edx  ;
         xo...[/QUOTE]

楼上的,是你搞错了。再仔细想想在内存中的排布
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hackerlx 2009-5-26 14:58
50
0
可我用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
这段代码是通过,,能得到基址,,用楼主的就不行,
游客
登录 | 注册 方可回帖
返回