|
bspmake的驱动学习笔记视频
谢谢bspmake 谢谢小娃崽 |
|
[讨论]学习手工脱壳有必要吗?
我对脱壳不大感兴趣,但对里面的算法和技术却非常感兴趣 |
|
[讨论]csdsjkk外壳学习
今天添上下面的代码,同时请高手们解释一下下面的疑惑. gfa6:之前已经算出了函数的具体的入口地址.为什么还要定义的DLL组 并且还要call f_LoadLibrary[ebx] ,以获得DLL的基址. 这个无法理解,是作者故弄玄虚吗.好像这样做是没必要的. 请求高手给予合理的解释. forwardchain_dll dd kernel32,user32,gdi32,ntdll,advapi32,ws2_32,mswsock,shlwapi dd 0 forwardchain_handle dd 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 dd 0 kernel32 db 'KERNEL32.dll',0 user32 db 'USER32.dll',0 gdi32 db 'GDI32.dll',0 ntdll db 'NTDLL.dll',0 advapi32 db 'ADVAPI32.dll',0 ws2_32 db 'WS2_32.dll',0 mswsock db 'MSWSOCK.dll',0 shlwapi db 'SHLWAPI',0 get_func_address proc stdcall uses ebx ecx edx esi edi base,p_funcname local save_ebx:dword mov save_ebx,ebx gfa1: mov ebx,base ;基址 mov eax,[ebx+3ch] ;'PE'头 mov eax,[ebx+eax+78h] ;export table 导出表 test p_funcname,80000000h ;测试函数是不是在80000000h以下, je gfa5 mov esi,[ebx+eax+24h] ;addr of ord 指向函数名序号表的RVA mov edx,[ebx+eax+14h] ;number of func 导出函数的起始序号 mov ecx,p_funcname ;函数名 and ecx,7fffffffh sub ecx,[ebx+eax+10h] cmp ecx,edx jae @@90 add ecx,ecx add ecx,ecx mov edi,ecx add edi,[ebx+eax+1ch] mov eax,[ebx+edi] add eax,ebx jmp gfa6 gfa5: cmp ebx,p_funcname ;与基址比较 ja @f ;;; mov eax,p_funcname ;;; jmp @@9 @@: mov esi,[ebx+eax+20h] ;addr of names 指向函数名地址表的RVA (函数名地址表:它的成员是指向函数名字符串的地址) mov edx,[ebx+eax+18h] ;number of names 以名称导出的函数总数 push eax @@0: mov ecx,p_funcname mov edi,[esi+ebx] ;内存中的函数表地址 @@: mov al,[edi+ebx] ;按字节比较 cmp al,[ecx] ;不是要找的函数就跳,然后继续找下一个 jne @f cmp al,0 ;看是否取完这个函数名的字符串 je @@1 inc edi ;取下个 inc ecx jmp @b ;循环检查在什么位置 @@: add esi,4 ;指向下一个导出函数地址(因为地址是一个字,占4个字节) dec edx ;取一个,就少一个了 jnz @@0 ;如果取了所有的函数,就做些清理工作,没有就再次回去找 mov eax,0 jmp @@9 @@1: pop eax ;export table sub esi,[ebx+eax+20h] ;指向函数名地址表的RVA 获得其偏移量 以算出序号(一个函数名地址占4字节) shr esi,1 ;除以2(因为每个序号是占2字节的) add esi,[ebx+eax+24h] ;addr of 序号 指向函数名序号表的RVA movzx esi,word ptr [ebx+esi] ;只取前面的2个字节 shl esi,2 ;乘以4 (一个函数名地址占4字节) add esi,[ebx+eax+1ch] ;addr of functions 指向导出函数地址表的RVA mov eax,[ebx+esi] add eax,ebx gfa6: mov ebx,save_ebx ;(还原ebx) check_int3 lea edx,forwardchain_dll[ebx] ;自己定义的DLL组 lea edi,forwardchain_handle[ebx] add eax,check2[ebx] gfa70: mov esi,[edx] cmp esi,0 je @@9 ;DLL组都查完了就返回 add esi,ebx ;重定位 push eax push esi dec esi dec eax gfa7: inc eax inc esi mov cl,[eax] cmp cl,'a' ;查看是否是字母 jb @f cmp cl,'z' ja @f and cl,0dfh @@: cmp cl,[esi] ;DLL组的DLL jne @f cmp cl,'.' je gfa75 ;在内存中搜索指定的DLL字符串 jmp gfa7 @@: pop esi pop eax add edx,4 add edi,4 jmp gfa70 gfa75: pop esi cmp dword ptr [edi],0 jne @f push eax push esi call f_LoadLibrary[ebx] ;获得DLL的基址 mov [edi],eax pop eax @@: inc eax add eax,check1[ebx] mov p_funcname,eax mov eax,[edi] mov base,eax ;DLL的基址 pop eax mov ebx,save_ebx jmp gfa1 @@90: mov eax,0 @@9: ret get_func_address endp |
|
[翻译]3个脱壳相关的重要函数介绍
哎,真历害,我都能看懂那么多API了,还不会脱壳,一个多线程就晕了 |
|
|
|
[讨论]csdsjkk外壳学习
由于分析水平有限,把一些简单的先贴上. 但还是有不清楚的地方. 或注释错误的地方. 若有的话,请朋友们指正下 各节的加密: encode proc stdcall uses ebx esi ecx edx p_offs,p_size,base,xz ; ret mov ebx,0 mov ecx,p_size ;节的大小 cmp ecx,4 ;是否低于4 jb ec9 sub ecx,3 ;每次处理3字节 mov esi,p_offs ;RVA对应的偏移量 add esi,xz ;计算节在文件中的位置 mov edx,base ;DOS头基址 ec_edit label byte ;!!! mov eax,'jdsg' ;!!! ;取字符串'jdsg'作初初始密钥 ec1: sub esi,xz ;新的ESI就是节的RVA invoke isnot?,esi ;检查是否在RVA为ESI的节内 pushf ;保护标志位不被修改,这里存取了数据有无取完的信息 add esi,xz ;计算所取数据是是否到节尾 popf jz @f ;以下是数据的加密 (数据是代码段时,每行都加密,为数据段时,只加密数据.不包括导入表) xor [esi+edx],eax ;把数据和密钥作XOR , ; ror eax,7 ;然后将密钥循环右移7位(这是高级加密,提高强度) add eax,7 ;得到的密钥再加7 @@: inc esi ;对下一数据加密 loop ec1 ec9: ret encode endp 各节的解密: decode proc stdcall uses esi ecx edx edi p_offs,p_size,base,xz ;这是解密程序 ; ret dc0: mov ecx,p_size ;节的长度 cmp ecx,4 ;如果比4还要少,肯定该节不存在 jb dc9 sub ecx,3 ;每次取3字节 mov esi,p_offs ;节的RVA add esi,xz ; check_int3 ;用RSTD检测有无中断 mov edx,base ;基址 dc_edit label byte ;!!! mov eax,'jdsg' ;!!! ;把这密钥'jdsg'取出来 dc1: sub esi,xz ; invoke isnot?,esi ;判断这个RVA在什么节中 pushf add esi,xz ;计算所取数据是是否到节尾 popf jz @f ;如果是节尾,则往下执行 push eax mov eax,-1 ;以下是数据的解密 ;int 0f7h mov edi,eax pop eax xor [esi+edx],eax ;把数据和密钥作XOR ; ror eax,7 add eax,7 ;得到的密钥再加7 ;xor [esi+edx],edi @@: inc esi loop dc1 ;继续取下一数据 dc9: ret ;解码完成,返回 decode endp |
|
[讨论]csdsjkk外壳学习
能否提供一个地址链接啊 下面这个是不是你写的呀 csdsjkk外壳脱壳笔记 -------------------------------------------------------------------------------- 摘自: 2006-04-03 03:09:54 看雪论坛 原程序下载地址:http://bbs.pediy.com/showthread.php?s=&threadid=22270 下面的代码中有几个地方搞不清楚 :[ebx+402156],FFFFFFFD///F4到这里。这段代码全部解压结束。 0046F20E 838B 3F214000 02 or dword ptr ds:[ebx+40213F],2 0046F218 ^ E9 12FFFFFF jmp 0046F12F 0046F227 83A3 56214000 FD and dword ptr ds:[ebx+402156],FFFFFFFD///新建EIP跳出循环。 0046F232 6A 00 push 0 0046F234 6A 00 push 0 0046F236 E8 A3E6FFFF call 0046D8DE///检测CC 0046F23E 838B F0204000 02 or dword ptr ds:[ebx+4020F0],2 0046F24A C9 leave 0046F24B C2 0400 retn 4///返回到系统代码。 77E1A990 50 push eax///返回到这里。 77E1A991 E8 E0D40000 call 77E27E76 ; ExitThread///F8过。 三、解压子进程代码 走过77E1A991时会陷入死循环。F12暂停。然后到0046F4A5处新建EIP。 0046F4A5 /EB 03 jmp short 0046F4AA///新建EIP。 0046F4A7 |9A 37A7EB01 9AEB call far EB9A:01EBA737 0046F4AE 039A E767EB01 add ebx,dword ptr ds:[edx+1EB67E7] 0046F4B4 9A EB039AB7 27E8 call far E827:B79A03EB 0046F4BB 0000 add byte ptr ds:[eax],al 0046F4BD 0000 add byte ptr ds:[eax],al 新建EIP后用F7走几步。 去花后: 0046F4C3 5B pop ebx 0046F4C9 81EB BF344000 sub ebx,4034BF 0046F4D4 EB 1C jmp short 0046F4F2 EIP为什么要在0046F227处建. mov esi,decode_start[ebx] 这里放入了解码代码的起始地址 对应壳的应该是 0046F4C3 5B pop ebx 为什么在上面的JMP那里新建EIP,而不是0046F4C3 这个,对应我写的程序是JNE,改EIP后,还要改标志位才能进解码代码 而且,这样进去的有些初始条件不满足,解码程序也不能正常工作.致使 后面就无法分析了. 另外,进入线程必须把所有的其它线程都挂掉吗? 在OD中,对于线程中的线程好像在线程窗口里看不到,更不能将其挂起了 只能用你的那种进入线程的方法. 是不是只能这样做啊 通过这篇笔记,学会了新的跟踪方法.在此向csjwaman您表示感谢 您上QQ吗. 我的QQ是330759606 风之guitar 希望能和您交个朋友. PE还是刚学,还有很多问题想请您指点一二呢. |
|
[讨论]csdsjkk外壳学习
现在还有很多问题,主要是跟踪得不准确.多线程能跟入,但出不来.特别是线程中有SEH的. 修改EIP后出来也很不正常.如果不能顺利跟踪就很难看懂源码.会给出错误的注释的. 这就会误人子弟了.自己弄错倒没什么,大家都弄错了.那可是偶的过失了. |
|
[讨论]csdsjkk外壳学习
谢谢老大的嘉奖,等把代码都分析透后,再放上源码 |
|
[讨论]csdsjkk外壳学习
看来,做好的注释也没必要再上传了. |
|
[讨论]csdsjkk外壳学习
奇怪,为什么响应的人这么少呢.高手就是不一样啊. |
|
[求助]如何用OD跟踪多线程
我是说用OD啊,线程地址是找得到的.拦截createthread就能看到了 |
|
[原创]为了加深C语言的学习,用不用学习汇编?
只要能看懂就可以了,你用VC的汇编级调试即可. |
|
[求助]请教有智慧的大哥大姐个比较入门的问题
为了使指令中存储单元操作数具有明确的属性,我们可以使用强制属性操作符PTR。其一般格式为: 数据类型 PTR 地址表达式 其中:数据类型是前面所学的各种数据类型,常用的数据类型有:BYTE、WORD、DWORD、NEAR和FAR等。 为了明确指令中存储单元的属性,可把指令“MOV [BX], 1H”可改写成: MOV byte ptr [BX], 1H 或 MOV word ptr [BX], 1H 在指令中用操作符PTR强制后,不管其后的地址表达式原数据类型是什么,在本指令中就以PTR前面的类型为准。该强制属性只在本指令有效,是一种临时性的属性,它不会改变原内存单元的定义属性。 例如: W1 DW 1234H, 5678H B1 DB 2 DB 5 D1 DD 23456789H … MOV AX, word ptr b1 ;把B1开始的二个字节拼接成一个字,执行后,(AX)=0502H MOV BH, byte ptr w1 ;把字W1的低字节传送给BH,执行后,(BH)=34H MOV CH, byte ptr w1+1 ;把字W1的高字节传送给CH,执行后,(CH)=12H MOV word ptr d1, 12H ;把双字D1的低字修改成0012H,执行后,(D1)=23450012H 上面指令中的强制属性是临时属性,它不能改变这些变量在定义时的永久属性。 |
|
[讨论]csdsjkk外壳学习
由于还处于研究阶段,所以还有好多没注释呢.以会后附上完整的源代码注释. 以附件方式传上来. 以供大家参考.新手学习. 如果有人对此已有研究,可以贴上你的心得.大家一块讨论. 附上加壳程序的源码 声明一下,之所以在这里上传是因为方便大家研究而已.内容并无修改 大家最好在csdsjkk的原版上下载 http://bbs.pediy.com/showthread.php?s=&threadid=22270 源码在第47楼 |
|
我以前写的一个壳(已放上源程序,在47楼)
开源就是硬道理.既然楼主这么慷慨.那一定不会反对附上注释吧. 这几天分析楼主的这个加壳程序.注释了一部分内容. 附上以帮助更多人读懂它.以后分析完后,再附上注释好的源码附件.注释的不一定对,请多指正. 程序太长,只能传上一小部分. st1: invoke VirtualProtect,addr entry,key_size,PAGE_READWRITE,addr temp1 ;改变内存页的保护属性 invoke GetTickCount push eax invoke GetTickCount pop edx mul edx mov dword ptr dc_edit+1,eax ;用获得MS级的时间作为随机数 mov dword ptr ec_edit+1,eax call calc_checksum ;制作两个代码的校验标志(0-所有代码中数据的字节和) invoke GetTickCount push eax invoke GetTickCount pop edx mul edx mov decode_key,eax ;用两个随机数相乘的值作为解码值. not eax mov rnd,eax mov esi,offset _ok mov edi,offset __ok mov eax,decode_key @@: ;把代码2编码,也就是加密 cmp esi,edi jae @f ;JAE/JNB CF=0 时跳转 xor [esi],al inc eax ror eax,7 ;eax循环右移>>7 inc esi jmp @b @@: invoke GetCommandLine call trans ;分解命令行 invoke CreateFile,addr fname1,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0 cmp eax,INVALID_HANDLE_VALUE je error1 mov hfile1,eax invoke CreateFile,addr fname2,GENERIC_WRITE,0,0,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,0 cmp eax,INVALID_HANDLE_VALUE je error3 mov hfile3,eax invoke GetFileSize,hfile1,0 mov fsize1,eax invoke VirtualAlloc,0,fsize1,MEM_COMMIT,PAGE_READWRITE mov pt1,eax invoke ReadFile,hfile1,pt1,fsize1,addr temp1,0 mov ebx,pt1 mov esi,[ebx+3ch] ;IMAGE_DOS_HEADER.e_lfanew cmp flag_clear_boundimport,0 je @f lea eax,[ebx+esi+0d0h] ;IMAGE_DIRECTORY_ENTRY_IAT.值为12 mov dword ptr [eax],0 mov dword ptr [eax+4],0 ;清空这个表 @@: cmp flag_clear_load_config,0 ;IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,值为11 je @f lea eax,[ebx+esi+0c8h] ;清空这个表(一般来说这两个表都不用.) @@: mov dword ptr [eax],0 mov dword ptr [eax+4],0 @@: mov eax,[ebx+esi+34h] ;指向ImageBase地址(RVA) mov image_base,eax push esi lea esi,[ebx+esi+78h] ;IMAGE_DIRECTORY_ENTRY_EXPORT,指向导出表 mov edi,offset rva_table ;DIRECTORY表 mov ecx,80h call move_memory ;调整各个表 pop esi cmp flag_add_section,0 ;标志 je @f add word ptr [ebx+esi+6],1 @@: mov eax,0 xchg eax,[ebx+esi+80h] ;IMAGE_DIRECTORY_ENTRY_IMPORT,指向导入表 mov iat_offs,eax ;保存IAT,然后清空IAT mov eax,0 xchg eax,[ebx+esi+84h] mov iat_size,eax mov eax,0 xchg eax,[ebx+esi+0a0h] ;IMAGE_DIRECTORY_ENTRY_BASERELOC,指向重定位表 mov reloc_offs,eax ;同样保存后清空 mov eax,0 xchg eax,[ebx+esi+0a4h] mov reloc_size,eax lea edi,[esi+0f8h] ;第一个节表 movzx eax,word ptr [ebx+esi+6] ;保存节的数目 mov temp1,eax st2: dec temp1 jz st3 jmp @f cmp dword ptr [ebx+edi+0ch],0 ;;;;;; je st3 cmp dword ptr [ebx+edi+08h],0 ;;;;;; je st3 @@: jmp st24 mov eax,dword ptr [ebx+esi+0a8h] cmp eax,0 je @f add eax,dword ptr [ebx+esi+0ach] cmp eax,dword ptr [ebx+edi+0ch] jb @f mov eax,dword ptr [ebx+edi+0ch] add eax,dword ptr [ebx+edi+8] cmp eax,dword ptr [ebx+esi+0a8h] ja st25 @@: mov eax,dword ptr [ebx+esi+88h] cmp eax,0 je @f add eax,dword ptr [ebx+esi+8ch] cmp eax,dword ptr [ebx+edi+0ch] jb @f mov eax,dword ptr [ebx+edi+0ch] add eax,dword ptr [ebx+edi+8] cmp eax,dword ptr [ebx+esi+88h] ja st25 @@: mov eax,dword ptr [ebx+esi+0c0h] cmp eax,0 je @f add eax,dword ptr [ebx+esi+0c4h] cmp eax,dword ptr [ebx+edi+0ch] jb @f mov eax,dword ptr [ebx+edi+0ch] add eax,dword ptr [ebx+edi+8] cmp eax,dword ptr [ebx+esi+0c0h] ja st25 @@: st24: mov eax,[ebx+edi+8] ;VirtualSize 节区大小 cmp eax,[ebx+edi+10h] ;SizeOfRawData 判断是否超过了对齐粒度 jbe @f mov eax,[ebx+edi+10h] @@: mov ecx,[ebx+edi+14h] ;PointerToRawData 在文件中的偏移 ;;;;;;add ecx,ebx mov edx,[ebx+edi+0ch] ;VirtualAddress 节区的RVA sub ecx,edx ; ;节区的RVA对应的偏移量 invoke encode,edx,eax,ebx,ecx ;对内存中的IAMAGE编码(加密被加壳的程序) st25: add edi,28h ;跳到下一个节(对每一节即代码,数据,资源都加密) jmp st2 st3: ;各节的加密已经完成了 push edi lea eax,[esi+0f8h] ;重新计算节的数目(最后节的节尾-起始节的节头)/节长 sub edi,eax mov edx,0 mov eax,edi mov edi,28h div edi mov number_of_section,eax pop edi cmp flag_add_section,0 ;引入的标志 jne st6 mov eax,fsize1 sub eax,[ebx+edi+14h] test eax,00000fffh jz @f add eax,1000h @@: and eax,0fffff000h push eax add eax,key_size test eax,00000fffh jz @f add eax,1000h @@: and eax,0fffff000h mov [ebx+edi+08h],eax mov [ebx+edi+10h],eax or dword ptr [ebx+edi+24h],0a0000020h ;mov dword ptr [ebx+edi+24h],0e0000040h pop ecx mov eax,[ebx+edi+0ch] add eax,ecx add eax,offset entry sub eax,offset entry xchg [ebx+esi+28h],eax mov shell_eip,eax jmp st7 st6: mov eax,key_size ;代码长度 test eax,00000fffh ;测试是否对齐(1000h*n) jz @f add eax,1000h @@: and eax,0fffff000h mov [ebx+edi+8],eax ;写入新节的内容 sub edi,28h mov eax,[ebx+edi+0ch] add eax,[ebx+edi+8] test eax,00000fffh je @f add eax,1000h @@: and eax,0fffff000h ;计算位置 add edi,28h mov [ebx+edi+0ch],eax ;VirtualAddress 节区的RVA地址 mov eax,key_size test eax,00000fffh jz @f add eax,1000h @@: and eax,0fffff000h mov [ebx+edi+10h],eax ;SizeOfRawData 在文件中对齐后的尺寸 mov eax,fsize1 test eax,00000fffh je @f add eax,1000h @@: and eax,0fffff000h mov [ebx+edi+14h],eax ; PointerToRawData 在文件中的偏移 mov dword ptr [ebx+edi+24h],0e0000020h ;Characteristics 节的属性 mov eax,[ebx+edi+0ch] add eax,offset entry sub eax,offset entry xchg [ebx+esi+28h],eax ;更改AddressOfEntryPoint mov shell_eip,eax ;入口 st7: mov eax,[ebx+edi+0ch] ;新节区的VirtualAddress 节区的RVA地址 add eax,[ebx+edi+8] ;VirtualSize 新节区的尺寸 test eax,00000fffh ;测试有没对齐 je @f add eax,1000h @@: and eax,0fffff000h mov [ebx+esi+50h],eax ;更改SizeOfImage 内存中整个PE映像尺寸 ;所有的文件头中要修改的部分都修改了 mov eax,decode_key ;解码键 xor shell_eip,eax lea esi,entry00 mov ecx,__ok - entry00 @@: not byte ptr [esi] ;加密entry00(解码加到被加壳文件的代码)的代码 inc esi loop @b mov flag_reentry,0 ;flag_reentry=0表示已加密 invoke WriteFile,hfile3,pt1,fsize1,addr temp1,0 ;写到新文件中(不过还是原文件的大小) cmp flag_add_section,0 ;标志 jne st75 mov eax,fsize1 sub eax,[ebx+edi+14h] mov ecx,1000h sub ecx,eax jns st71 @@: add ecx,1000h js @b st71: mov eax,ecx jmp st8 st75: mov eax,fsize1 ;新文件的长度 test eax,00000fffh ;有无对齐 je @f add eax,1000h @@: and eax,0fffff000h sub eax,fsize1 st8: lea ecx,_fill invoke WriteFile,hfile3,ecx,eax,addr temp1,0 ;写入_fill处的数据.现在是空值(加大1K) mov eax,key_size test eax,00000fffh jz @f add eax,1000h @@: and eax,0fffff000h invoke WriteFile,hfile3,addr entry,eax,addr temp1,0 ;写入entry代码 invoke CloseHandle,hfile1 ;关闭这两个文件 invoke CloseHandle,hfile3 invoke VirtualFree,pt1,0,MEM_RELEASE invoke CreateFile,addr fname2,GENERIC_READ + GENERIC_WRITE,0,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0 cmp eax,INVALID_HANDLE_VALUE je error3 mov hfile1,eax invoke GetFileSize,hfile1,0 ;得到文件的大小,用于后面读出全部内容 mov fsize1,eax invoke VirtualAlloc,0,fsize1,MEM_COMMIT,PAGE_READWRITE ;分配虚拟内存 mov pt1,eax invoke ReadFile,hfile1,pt1,fsize1,addr temp1,0 ;把文件读入缓冲区pt1中 mov ecx,fsize1 mov edi,pt1 uu1: cmp ecx,8 ;在文件中有无'LiNr'和'VoTa'字符串 jb nofound cmp dword ptr [edi],'LiNr' ;'rNiL' ;加壳后的标志'rNiLaToV' jne uu2 cmp dword ptr [edi+4],'VoTa' ;'aToV' je found uu2: inc edi loop uu1 jmp nofound found: ;已加壳了 add edi,8 sub edi,pt1 ;获得标志'rNiLaToV'的偏移量 mov ebx,pt1 mov esi,[ebx+3ch] ;获得PE头位置 movzx ecx,word ptr [ebx+esi+6] ;扩展为双字NumberOfSections mov eax,[ebx+esi+74h] ; NumberOfRvaAndSizes shl eax,3 ;NumberOfRvaAndSizes*8(每个IMAGE_DATA_DIRECTORY 8字节) lea edx,[ebx+esi+78h] ;IMAGE_DIRECTORY_ENTRY_EXPORT add edx,eax ;得到节表的位置 uu3: cmp dword ptr [edx+14h],edi ;PointerToRawData 在文件中的偏移 ja s_nt mov eax,[edx+8] ;VirtualSize 节区的尺寸 add eax,[edx+14h] ;得到代码段的位置 cmp eax,edi jbe s_nt ;超过的话,执行下面的代码 mov eax,edi ;文件尾 sub eax,[edx+14h] ;算出所余的空间 add eax,[edx+0ch] ;VirtualAddress 节区的RVA地址(把这个作为导入表的地址) mov [ebx+esi+80h],eax ;IMAGE_DIRECTORY_ENTRY_IMPORT的VirtualAddress mov dword ptr [ebx+esi+84h],14h ;IMAGE_DIRECTORY_ENTRY_IMPORT的isize(数据块的长度) lea ecx,[eax+size1] ; mov [ebx+edi+0ch],ecx ;VirtualAddress 节区的RVA地址 lea ecx,[eax+size1+size2] ;加上DLL的长度后的RVA mov [ebx+edi+size1+size2+size3],ecx ;在原来的函数表后面再填上这个RVA lea ecx,[eax+size1+size2+size3] ;算出新的RVA mov [ebx+edi+10h],ecx ;SizeOfRawData 在文件中对齐后的尺寸 jmp found1 s_nt: add edx,28h ;没超过的话,取下个节 loop uu3 jmp nofound found1: invoke SetFilePointer,hfile1,0,0,FILE_BEGIN invoke WriteFile,hfile1,pt1,fsize1,addr temp1,0 ;重写,更改了IAT了.原来全是0 nofound: invoke CloseHandle,hfile1 ;关闭原文件 invoke VirtualFree,pt1,0,MEM_RELEASE ;释放分配的内存 error1: error2: error3: exit0: invoke ExitProcess,0 ;退出进程,程序终止 _fill db 1000h dup (0) ;填充数据0 end start |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值