去年学习汇编的时候写的内存LOADer

发布于 2014-12-08  192 次阅读


.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
checkcodesum proto n:dword,z:dword
writereloc proto ntheader:dword,dosheader:dword
xxx equ 3451
.data
axx dword 00
sizex dword 00
address dword 00
.code
org 00500000h
mem_load_dll proc lpaddress:dword
LOCAL pNtHeader,pOptionalHead,pSecHeader,pDosHeader,ImageBase,SizeOfImage,SectionAlignment,lpstartaddress,SizeOfHeaders,NumberOfSections
LOCAL RawSize,VirtualSize,pbPhysicalPE,VirtualAddress,pbPhysicalPEx
LOCAL pExportTable,dwExportSize
LOCAL pImportTable,pImportSize
LOCAL relocationaddress,relocationsize
LOCAL delta,lpstartaddressex
pushad
push lpaddress
pop pDosHeader;DOS头
mov eax,dword ptr [pDosHeader] mov eax,dword ptr [eax+IMAGE_DOS_HEADER.e_lfanew] add eax,dword ptr [pDosHeader] push eax
pop pNtHeader
lea eax,dword ptr [eax+IMAGE_NT_HEADERS.OptionalHeader] push eax
pop pOptionalHead
;可选头数据筛选
mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.ImageBase] mov dword ptr [ImageBase],ebx
mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.SizeOfImage] mov dword ptr [SizeOfImage],ebx
mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.SectionAlignment] mov dword ptr [SectionAlignment],ebx
mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.SizeOfHeaders] mov dword ptr [SizeOfHeaders],ebx
;筛选结束
mov eax,dword ptr [pNtHeader];NT头部
;拿到文件头
movzx ebx,word ptr [eax+IMAGE_NT_HEADERS.FileHeader.NumberOfSections];节数目
mov dword ptr [NumberOfSections],ebx
;文件头结束
;拿到节信息首部(第一个区段信息)
add eax,sizeof IMAGE_OPTIONAL_HEADER
add eax,sizeof IMAGE_FILE_HEADER
add eax,4
push eax
pop pSecHeader;这里指向第一个节 加上IMAGE_SECTION_HEADER(28)指向下一个节
invoke VirtualAlloc,NULL,SizeOfImage,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
mov dword ptr [lpstartaddress],eax
mov dword ptr [lpstartaddressex],eax
invoke RtlMoveMemory,lpstartaddress,lpaddress,SizeOfHeaders ;PE头先移动过去
add dword ptr [lpstartaddressex],4096
;下面开始复制区段信息

mov ecx,dword ptr [NumberOfSections];节数目交给ECX
xor ebx,ebx

loop_copy:
mov eax,ebx
mov edx,sizeof IMAGE_SECTION_HEADER
mul edx;此时pSecHeader+eax作为节指针
mov edx,dword ptr [pSecHeader] add edx,eax ;指针处理
mov eax,dword ptr [edx+IMAGE_SECTION_HEADER.SizeOfRawData] mov dword ptr [RawSize],eax
mov eax,dword ptr [edx+IMAGE_SECTION_HEADER.Misc.VirtualSize] mov dword ptr [VirtualSize],eax
mov eax,dword ptr [edx+IMAGE_SECTION_HEADER.PointerToRawData] mov dword ptr [pbPhysicalPE],eax
mov eax,dword ptr [edx+IMAGE_SECTION_HEADER.VirtualAddress] mov dword ptr [VirtualAddress],eax

push ecx

invoke checkcodesum ,VirtualSize,SectionAlignment
push eax
mov eax,dword ptr [lpaddress] add eax,dword ptr [pbPhysicalPE] mov dword ptr [pbPhysicalPEx],eax
mov edi,dword ptr [lpstartaddressex] mov esi,dword ptr [pbPhysicalPEx] mov ecx,dword ptr [RawSize] cld
rep movsb
mov eax,dword ptr [lpstartaddressex] pop esi
add eax,esi
mov dword ptr [lpstartaddressex],eax
pop ecx
inc ebx
loop loop_copy

;这里区段信息已经填充完毕

;下面填充导出表

;这是修正后的 就差修复导入和导出表还有重定位数据就完事儿了
mov eax,dword ptr [pNtHeader] sub eax,dword ptr [lpaddress] add eax,dword ptr [lpstartaddress] mov dword ptr [pNtHeader],eax
lea eax,[eax+IMAGE_NT_HEADERS.OptionalHeader] mov dword ptr [pOptionalHead],eax

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][0*4] add ebx,dword ptr[lpstartaddress];;指向导出表地址修正后
mov dword ptr [pExportTable],ebx

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][1*4] mov dword ptr [dwExportSize],ebx;指向导出表大小

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][2*4] add ebx,dword ptr[lpstartaddress] mov dword ptr [pImportTable],ebx;导入表

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][3*4] mov dword ptr [pImportSize],ebx;导入表大小

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][IMAGE_DIRECTORY_ENTRY_BASERELOC*4*2] add ebx,dword ptr[lpstartaddress] mov dword ptr [relocationaddress],ebx;重定位表

mov ebx,dword ptr [eax+IMAGE_OPTIONAL_HEADER.DataDirectory][IMAGE_DIRECTORY_ENTRY_BASERELOC*4*2][4] mov dword ptr [relocationsize],ebx;重定位表大小

mov eax,dword ptr [lpstartaddress] sub eax,dword ptr [ImageBase] mov dword ptr [delta],eax;用作修正重定位表的数据

mov eax,dword ptr [relocationaddress] mov eax,[eax+IMAGE_BASE_RELOCATION.VirtualAddress]

mov edx,dword ptr [lpstartaddress] mov eax,dword ptr [pNtHeader] call tianchongiat;填充导入表
invoke writereloc,pNtHeader,lpstartaddress
mov eax,dword ptr [pNtHeader] mov eax,dword ptr [eax+28h];入口点
add eax,dword ptr [lpstartaddress] push 0
push lpstartaddress
push 0
call eax

;.if dword ptr [pExportTable]!=0
;mov eax,dword ptr [pExportTable] ;mov ebx,dword ptr [eax+IMAGE_EXPORT_DIRECTORY.AddressOfFunctions] ;add ebx,dword ptr[lpstartaddress] ;mov ecx,dword ptr [eax+IMAGE_EXPORT_DIRECTORY.NumberOfFunctions] ;loop_writeexptable:

;mov eax,dword ptr[ebx] ;add eax,dword ptr [lpstartaddress] ;mov dword ptr [ebx],eax
;add ebx,4
;loop loop_writeexptable
;.endif

;76ABC924
popad

ret
mem_load_dll endp
writereloc proc ntheader:dword,dosheader
pushad
mov eax,dword ptr [ntheader] mov esi,dword ptr [eax+0A0H] add esi,dword ptr [dosheader];重定位数据第一块
cld
loop_reloc:
cmp dword ptr [esi],0;判断有没有重定位数据,没有这里负责的修正块地址就是0
je relocend
lodsd
xchg eax,ebx;这是第一个小偏移
lodsd
xchg eax,ecx;数据块大小
sub ecx,8
shr ecx,1
loop_coc_relocdata:
lodsw
and eax,0ffh
add eax,ebx
add eax,dword ptr [dosheader] mov edi,dword ptr [eax] and edi,0ffffh
add edi,dword ptr [dosheader] mov [eax],edi
loop loop_coc_relocdata
jmp loop_reloc
relocend:
popad
mov eax,1;处理完毕返回一个1
ret
writereloc endp
checkcodesum proc n,A:dword
;端对齐
push ebx
push esi
push edi
mov eax,dword ptr [n] xor edx,edx
div dword ptr [A] mov ecx,eax
mov eax,dword ptr [n] xor edx,edx
div dword ptr [A] neg edx
sbb edx,edx
neg edx
add ecx,edx
imul ecx,dword ptr [A] mov eax,ecx
pop edi
pop esi
pop ebx

ret
checkcodesum endp
;00210000
;00210000
;00904060
mem_load_dll2:
pushad
mov ebx,dword ptr [esp+4*8+4] cmp word ptr [ebx],5A4Dh
JNZ ret0
push ebx
mov edi,ebx
add edi,dword ptr [edi+03ch] cmp word ptr [edi],4550h
jnz ret0
push 40h
push 1000h
push dword ptr [edi+50h] push 0
call VirtualAlloc
test eax,eax
je ret0
xchg eax,ebp
lea esi,dword ptr [edi+14h] xor eax,eax
lods word ptr [esi] lea esi,dword ptr [esi+eax+2h] movzx ecx,word ptr [edi+6h] loop_copy_sec:
push ecx
mov edx,dword ptr [esi+14h] add edx,dword ptr [esp+4h] mov eax,dword ptr [esi+0ch] add eax,ebp
push dword ptr [esi+10h] push edx
push eax
call RtlMoveMemory
add esi,28h
pop ecx
loop loop_copy_sec
mov edx,ebp
mov eax,edi
call tianchongiat
mov edx,ebp
mov eax,edi
call tianchongiat2
mov edx,dword ptr [edi+28h] add edx,ebp
push 0
push 1
push ebp
call edx
ret0:
mov eax,0
ret

tianchongiat2:
pushad
mov esi,dword ptr [eax+0a0h] test esi,esi
je tian1
cld
add esi,edx
push dword ptr [eax+0a4h] add dword ptr [esp],esi
mov edi,edx
mov ebp,edx
sub ebp,dword ptr[eax+34h] longjmp_loop:
cmp dword ptr [esp],esi
je tian2
lods dword ptr[esi] xchg eax,ebx
lods dword ptr [esi] xchg eax,ecx
sub ecx,8h
shr ecx,1
xor eax,eax
lods word ptr [esi] bt eax,0dh
loop__:
jnb jnbjump
and ax,0fffh
add eax,ebx
ADD DWORD PTR [EDI+EAX],EBP
jnbjump:
loop loop__
jmp longjmp_loop
tian2:
pop edx
popad
xor eax,eax
inc eax
ret
tian1:
popad
xor eax,eax
ret

tianchongiat:
pushad
push edx
mov edi,dword ptr [eax+80h] add edi,edx
addedi2:
cmp dword ptr [edi+0ch],0
je neibu1
mov edx,dword ptr [edi+0ch] add edx,dword ptr [esp] push edx
call LoadLibrary
test eax,eax
je neibu2
xchg eax,ebx
mov esi,dword ptr [edi+10h] add esi,dword ptr [esp] cld
loop_lods:
lods dword ptr [esi] test eax,eax
je addedi
bt eax,1Fh
jnb notget
movzx edx,ax
push edx
push ebx
call GetProcAddress
mov dword ptr [esi-4],eax
jmp loop_lods
notget:
add eax,dword ptr[esp] lea edx,dword ptr [eax+2h] push edx
push ebx
call GetProcAddress
mov dword ptr [esi-4h],eax
jmp loop_lods
addedi:
add edi,14h
jmp addedi2
neibu1:
pop edx
popad
xor eax,eax
inc eax
ret
neibu2:
pop edx
popad
xor eax,eax
ret

start:

invoke FindResource,NULL,xxx,RT_RCDATA
mov axx,eax
invoke LoadResource,NULL,eax
invoke LockResource,eax
mov address,eax
invoke SizeofResource,NULL,axx
mov sizex,eax
push address
call mem_load_dll
ret
end start
在我的不懈努力下成功了

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

博客管理员