001 ;找个时间,把上次还没搞完的应用给补上,用OD加载上次脱过壳的产品,在如下函数上下断:
002 TerminateProcess
003 SetWindowsHookExA
004 UnhookWindowsHookEx
005 MessageBoxA
006 lstrlenA
007 lstrcatA
008 GetWindowTextA
009 GetWindowThreadProcessId
010 CreateEventA
011 CreateFileA
012 CreateMutexA
013 CreateProcessA
014 CreateServiceA
015 CreateThread
016 CreateToolhelp32Snapshot
017 DeviceIoControl
018 fopen
019 ;搞定之后,F9,断在lstrcatA,可以发现它在进行字符串连接,然后就是写注册表启动项:
020 004019AB 68 80000000 push 80
021 004019B0 68 1E344000 push Rtvcan_u.0040341E ; ASCII "C:/WINNT/system32/Rtvcan.exe"
022 004019B5 E8 04050000 call <jmp.&KERNEL32.GetSystemDirecto>
023 004019BA 68 1E344000 push Rtvcan_u.0040341E ; ASCII "C:/WINNT/system32/Rtvcan.exe"
024 004019BF E8 2A050000 call <jmp.&KERNEL32.SetCurrentDirect>
025 004019C4 68 03344000 push Rtvcan_u.00403403 ; ASCII "/Rtvcan.exe"
026 004019C9 68 1E344000 push Rtvcan_u.0040341E ; ASCII "C:/WINNT/system32/Rtvcan.exe"
027 004019CE E8 3F050000 call <jmp.&KERNEL32.lstrcat> ;断在这里
028 004019D3 68 16344000 push Rtvcan_u.00403416
029
030 ;这里有个比较不合理的地方,它已经将路径进行了硬编码,即使Rtccan.exe不在system32目录下,它也会;按照这种写入。
031 ;往下翻翻代码就会看见,它打开文件了//./Rtvcan,这里它倒是有判断,但由于该驱动已经被停,所以它会;弹出一个错误对话框。
032 00401A42 68 3B214000 push Rtvcan_u.0040213B ; ASCII "//./Rtvcan"
033 00401A47 E8 0C040000 call <jmp.&KERNEL32.CreateFileA>
034 00401A4C A3 00304000 mov dword ptr ds:[403000],eax ;保存文件句柄
035 00401A51 83F8 FF cmp eax,-1
036 00401A54 75 0F jnz short Rtvcan_u.00401A65 ;不失败则跳
037
038 ;为了满足想看看这运行效果的好奇心,启动它的驱动(你可以用4F的KmdManager),运行,竟然没看见界面
039 ;汗..
040 ;接着干活,
041 00401A4C A3 00304000 mov dword ptr ds:[403000],eax ; 保存文件句柄
042 00401A51 83F8 FF cmp eax,-1
043 00401A54 75 0F jnz short Rtvcan_u.00401A65
044 00401A56 E8 CDF5FFFF call Rtvcan_u.00401028
045 00401A5B E8 0FF6FFFF call Rtvcan_u.0040106F
046 00401A60 A3 00304000 mov dword ptr ds:[403000],eax
047 00401A65 833D 00304000 FF cmp dword ptr ds:[403000],-1 ; 打开文件是否失败
048 00401A6C 0F84 2A010000 je Rtvcan_u.00401B9C
049 00401A72 6A 00 push 0
050 00401A74 6A 00 push 0
051 00401A76 6A 00 push 0
052 00401A78 6A 00 push 0
053 00401A7A E8 D3030000 call <jmp.&KERNEL32.CreateEventA>
054 00401A7F A3 04304000 mov dword ptr ds:[403004],eax ; 保存事件句柄
055 00401A84 51 push ecx
056 00401A85 54 push esp
057 00401A86 6A 00 push 0
058 00401A88 FF35 04304000 push dword ptr ds:[403004] ; 将事件句柄传给线程
059 00401A8E 68 FA184000 push Rtvcan_u.004018FA ; 线程函数
060 00401A93 6A 00 push 0
061 00401A95 6A 00 push 0
062 00401A97 E8 CE030000 call <jmp.&KERNEL32.CreateThread>
063 00401A9C 59 pop ecx
064 00401A9D 0BC0 or eax,eax
065 00401A9F 0F84 9B000000 je Rtvcan_u.00401B40
066 00401AA5 50 push eax
067 00401AA6 E8 A1030000 call <jmp.&KERNEL32.CloseHandle>
068 00401AAB 6A 00 push 0
069 00401AAD 8D45 FC lea eax,dword ptr ss:[ebp-4] ; DWORD dwReted
070 00401AB0 50 push eax ; push &dwReted
071 00401AB1 6A 00 push 0
072 00401AB3 6A 00 push 0
073 00401AB5 6A 04 push 4 ; 缓冲大小
074 00401AB7 68 04304000 push Rtvcan_u.00403004 ; 输入缓冲区
075 00401ABC 68 00A02200 push 22A000 ; 控制代码
076 00401AC1 FF35 00304000 push dword ptr ds:[403000]
077 00401AC7 E8 B0030000 call <jmp.&KERNEL32.DeviceIoControl>
078 00401ACC 0BC0 or eax,eax
079 00401ACE 74 5E je short Rtvcan_u.00401B2E
080 00401AD0 6A 00 push 0
081 00401AD2 E8 DB030000 call <jmp.&KERNEL32.GetModuleHandleA>
082 00401AD7 A3 08304000 mov dword ptr ds:[403008],eax ; 本模块
083 00401ADC E8 28F7FFFF call Rtvcan_u.00401209
084 00401AE1 6A 00 push 0
085 00401AE3 8D45 FC lea eax,dword ptr ss:[ebp-4]
086 00401AE6 50 push eax
087 00401AE7 6A 00 push 0
088 00401AE9 6A 00 push 0
089 00401AEB 6A 00 push 0
090 00401AED 6A 00 push 0
091 00401AEF 68 04202200 push 222004 ; 控制代码
092 00401AF4 FF35 00304000 push dword ptr ds:[403000]
093 00401AFA E8 7D030000 call <jmp.&KERNEL32.DeviceIoControl>
094 ;可以看到它在这里创建了一个线程,线程函数地址是004018FA,现在我们就去看看它在线程函数里干什么了;:
095 004018FA 55 push ebp ; 线程函数
096 004018FB 8BEC mov ebp,esp
097 004018FD 83C4 F4 add esp,-0C
098 00401900 C745 F8 20030000 mov dword ptr ss:[ebp-8],320 ; 分配320字节
099 00401907 FF75 F8 push dword ptr ss:[ebp-8]
100 0040190A E8 F1F6FFFF call Rtvcan_u.00401000 ; 分配内存
101 0040190F 0BC0 or eax,eax
102 00401911 0F84 83000000 je Rtvcan_u.0040199A ; 失败则结束线程
103 00401917 8945 FC mov dword ptr ss:[ebp-4],eax ; 保存分配到的内存
104 0040191A 6A FF push -1
105 0040191C FF75 08 push dword ptr ss:[ebp+8] ; 在此事件上等待
106 0040191F E8 E8050000 call <jmp.&KERNEL32.WaitForSingleObject>; 等待
107 00401924 83F8 FF cmp eax,-1
108 00401927 74 51 je short Rtvcan_u.0040197A
109 00401929 833D 14304000 01 cmp dword ptr ds:[403014],1 ;一个标志位
110 00401930 74 60 je short Rtvcan_u.00401992 ; 等于1则结束
111 00401932 6A 64 push 64
112 00401934 E8 C7050000 call <jmp.&KERNEL32.Sleep> ; 休息0.064秒
113 00401939 6A 00 push 0
114 0040193B 8D45 F4 lea eax,dword ptr ss:[ebp-C] ; DWORD dwReted
115 0040193E 50 push eax ; push &dwReted
116 0040193F FF75 F8 push dword ptr ss:[ebp-8] ; 缓冲区大小
117 00401942 FF75 FC push dword ptr ss:[ebp-4] ; 输出缓冲区
118 00401945 6A 00 push 0
119 00401947 6A 00 push 0
120 00401949 68 08602200 push 226008 ; 控制代码
121 0040194E FF35 00304000 push dword ptr ds:[403000] ; 设备句柄
122 00401954 E8 23050000 call <jmp.&KERNEL32.DeviceIoControl>
123 00401959 0BC0 or eax,eax
124 0040195B 74 11 je short Rtvcan_u.0040196E
125 0040195D 837D F4 00 cmp dword ptr ss:[ebp-C],0 ; 如果返回字节数为0
126 00401961 74 0B je short Rtvcan_u.0040196E
127 00401963 FF75 F4 push dword ptr ss:[ebp-C] ; 返回字节数
128 00401966 FF75 FC push dword ptr ss:[ebp-4] ; 输出缓冲区
129 00401969 E8 73FEFFFF call Rtvcan_u.004017E1
130 0040196E 68 84030000 push 384
131 00401973 E8 88050000 call <jmp.&KERNEL32.Sleep> ; 又休息
132 00401978 EB 16 jmp short Rtvcan_u.00401990
133 0040197A 6A 10 push 10
134 0040197C 6A 00 push 0
135 0040197E 68 46214000 push Rtvcan_u.00402146 ; ASCII "Wait failed. Thread now exits. Restart application."
136 00401983 FF35 0C304000 push dword ptr ds:[40300C]
137 00401989 E8 94040000 call <jmp.&USER32.MessageBoxA>
138 0040198E EB 02 jmp short Rtvcan_u.00401992
139 00401990 ^ EB 88 jmp short Rtvcan_u.0040191A ; 继续循环
140 00401992 FF75 FC push dword ptr ss:[ebp-4]
141 00401995 E8 7AF6FFFF call Rtvcan_u.00401014 ; 释放内存
142 0040199A 6A 00 push 0
143 0040199C E8 E7040000 call <jmp.&KERNEL32.ExitThread>
144 004019A1 C9 leave
145 004019A2 C2 0400 retn 4
146
147 ;在线程里它会通过DeviceIoControl向驱动要数据,然后通过00401969处的CALL进一步处理,在00401ADC处;的CALL 00401209的代码中,它先会用互斥来保证单实例运行,然后通过RegisterHotKey注册F11,再然后;就是钩子了,钩子函数地址是0040127F,会在函数中监视键盘,当然也会有其它的操作如枚举DLL等,
148 ;由于这个钩子有点碍事,所以得将00401DAC处的调用NOP掉,继续F8就会发现紧随其后的DeviceIoControl;调用失败,调试到此结束。除以上说的这些之外,它还会创建文件并发送,这个在上次就已经提到了。
149
150 ;太累了,睡觉去
终于补课了:Rtvcan.exe
最新推荐文章于 2024-06-24 10:24:55 发布