haha0518 发表于 2017-6-3 11:11:20

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


.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
xxxequ 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
mov eax,dword ptr
add eax,dword ptr
push eax
pop pNtHeader
lea eax,dword ptr
push eax
pop pOptionalHead
;可选头数据筛选
mov ebx,dword ptr
mov dword ptr ,ebx
mov ebx,dword ptr
mov dword ptr ,ebx
mov ebx,dword ptr
mov dword ptr ,ebx
mov ebx,dword ptr
mov dword ptr ,ebx
;筛选结束
mov eax,dword ptr ;NT头部
;拿到文件头
movzx ebx,word ptr ;节数目
mov dword ptr ,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 ,eax
mov dword ptr ,eax
invoke RtlMoveMemory,lpstartaddress,lpaddress,SizeOfHeaders ;PE头先移动过去
add dword ptr ,4096
;下面开始复制区段信息

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



loop_copy:
mov eax,ebx
mov edx,sizeof IMAGE_SECTION_HEADER
mul edx;此时pSecHeader+eax作为节指针
mov edx,dword ptr
add edx,eax ;指针处理
mov eax,dword ptr
mov dword ptr ,eax
mov eax,dword ptr
mov dword ptr ,eax
mov eax,dword ptr
mov dword ptr ,eax
mov eax,dword ptr
mov dword ptr ,eax







push ecx

invoke checkcodesum ,VirtualSize,SectionAlignment
push eax
mov eax,dword ptr
add eax,dword ptr
mov dword ptr ,eax
mov edi,dword ptr
mov esi,dword ptr
mov ecx,dword ptr
cld
rep movsb
mov eax,dword ptr
pop esi
add eax,esi
mov dword ptr ,eax
pop ecx
inc ebx
loop loop_copy

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

;下面填充导出表


;这是修正后的 就差修复导入和导出表还有重定位数据就完事儿了
mov eax,dword ptr
sub eax,dword ptr
add eax,dword ptr
mov dword ptr ,eax
lea eax,
mov dword ptr ,eax

mov ebx,dword ptr
add ebx,dword ptr;;指向导出表地址修正后
mov dword ptr ,ebx

mov ebx,dword ptr
mov dword ptr ,ebx;指向导出表大小

mov ebx,dword ptr
add ebx,dword ptr
mov dword ptr ,ebx;导入表

mov ebx,dword ptr
mov dword ptr ,ebx;导入表大小

mov ebx,dword ptr
add ebx,dword ptr
mov dword ptr ,ebx;重定位表

mov ebx,dword ptr
mov dword ptr ,ebx;重定位表大小

mov eax,dword ptr
sub eax,dword ptr
mov dword ptr ,eax;用作修正重定位表的数据


mov eax,dword ptr
mov eax,





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

;.if dword ptr !=0
;mov eax,dword ptr
;mov ebx,dword ptr
;add ebx,dword ptr
;mov ecx,dword ptr
;loop_writeexptable:

;mov eax,dword ptr
;add eax,dword ptr
;mov dword ptr ,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
mov esi,dword ptr
add esi,dword ptr ;重定位数据第一块
cld
loop_reloc:
cmp dword ptr ,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
mov edi,dword ptr
and edi,0ffffh
add edi,dword ptr
mov ,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
xor edx,edx
div dword ptr
mov ecx,eax
mov eax,dword ptr
xor edx,edx
div dword ptr
neg edx
sbb edx,edx
neg edx
add ecx,edx
imul ecx,dword ptr
mov eax,ecx
pop edi
pop esi
pop ebx

ret
checkcodesum endp
;00210000
;00210000
;00904060
mem_load_dll2:
pushad
mov ebx,dword ptr
cmp word ptr ,5A4Dh
JNZ ret0
push ebx
mov edi,ebx
add edi,dword ptr
cmp word ptr ,4550h
jnz ret0
push 40h
push 1000h
push dword ptr
push 0
call VirtualAlloc
test eax,eax
je ret0
xchg eax,ebp
lea esi,dword ptr
xor eax,eax
lods word ptr
lea esi,dword ptr
movzx ecx,word ptr
loop_copy_sec:
push ecx
mov edx,dword ptr
add edx,dword ptr
mov eax,dword ptr
add eax,ebp
push dword ptr
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
add edx,ebp
push 0
push 1
push ebp
call edx
ret0:
mov eax,0
ret



tianchongiat2:
pushad
mov esi,dword ptr
test esi,esi
je tian1
cld
add esi,edx
push dword ptr
add dword ptr ,esi
mov edi,edx
mov ebp,edx
sub ebp,dword ptr
longjmp_loop:
cmp dword ptr ,esi
je tian2
lods dword ptr
xchg eax,ebx
lods dword ptr
xchg eax,ecx
sub ecx,8h
shr ecx,1
xor eax,eax
lods word ptr
bt eax,0dh
loop__:
jnb jnbjump
and ax,0fffh
add eax,ebx
ADD DWORD PTR ,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
add edi,edx
addedi2:
cmp dword ptr ,0
je neibu1
mov edx,dword ptr
add edx,dword ptr
push edx
call LoadLibrary
test eax,eax
je neibu2
xchg eax,ebx
mov esi,dword ptr
add esi,dword ptr
cld
loop_lods:
lods dword ptr
test eax,eax
je addedi
bt eax,1Fh
jnb notget
movzx edx,ax
push edx
push ebx
call GetProcAddress
mov dword ptr ,eax
jmp loop_lods
notget:
add eax,dword ptr
lea edx,dword ptr
push edx
push ebx
call GetProcAddress
mov dword ptr ,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
在我的不懈努力下成功了
页: [1]
查看完整版本: 去年学习汇编的时候写的内存LOADer