.386
.model flat,stdcall
option casemap:none

.data
correy db "made by correy",0
szGetProcAddress db "GetProcAddress",0 
szLoadLibrary db 'LoadLibraryA',0
szUser32 db 'user32',0
szmessagebox db 'MessageBoxA',0

.data?
pe dd ?;
OptionalHeader dd ?;
header dd ? ;
sizeOfOptionalHeader dd ?;
sections dd ?
nnps dd ?
e dd ?;
k dd ?;
apiaddress dd ?;
apinameaddress dd ?;
ordinaladdress dd ?;
apis dd ? 
n dd ?;
i dd ?;
o dd ?;
f dd ?;
ob dd ?
ipapiloadlibrary dd ?
ipapiuser32 dd ?
ipapimessagebox dd ?

.code

lenstr proc s
local z
mov eax,s
mov z,eax
xor eax,eax
pop ecx
comp:cmp byte ptr [ecx],0
je exit2
inc eax
inc ecx
jmp comp
exit2:ret
lenstr endp

strcat proc s1,s2
invoke lenstr,s1
add s1,eax
mov esi,s2
mov edi,s1
invoke lenstr,s2
mov ecx,eax
rep movsb
ret
strcat endp

start:
push [esp]
mov edi,[esp]
and edi,0ffff0000h
againk:push edi
cmp word ptr [edi],5a4dh
jne nextk
add edi,[edi+3ch]
cmp word ptr [edi],4550h
jne nextk
pop edi
mov eax,edi
jmp showk
nextk:pop edi
sub edi,10000h
jmp againk
showk:mov k,eax
add eax,3ch
mov eax,[eax]
add eax,k
mov pe,eax

mov esi,pe
add esi,6
mov dx,word ptr [esi]
movsx edx,dx
mov sections,edx

mov esi,pe
add esi,24
mov OptionalHeader,esi ;保存可选头的地址。

mov esi,pe
add esi,20
mov dx,word ptr [esi]
movsx edx,dx
mov sizeOfOptionalHeader,edx

mov esi,OptionalHeader 
add esi,sizeOfOptionalHeader
mov header,esi ;保存节头的地址。

mov esi,OptionalHeader
add esi,96
mov esi,[esi]
mov edi,esi

add esi,k
add edi,k
mov e,edi;导出节或导出目录表的首地址

mov edi,e
add edi,12
mov edi,[edi]
add edi,k

mov edi,e
add edi,16
mov edi,[edi]
mov ob,edi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edi,e
add edi,20
mov edi,[edi]
mov apis,edi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edi,e
add edi,24
mov edi,[edi]
mov nnps,edi

mov edi,e
add edi,28
mov edi,[edi]
add edi,k 
mov apiaddress,edi ;导出地址表的首地址

mov edi,e
add edi,32
mov edi,[edi]
add edi,k 
mov apinameaddress,edi ;导出名称指针表的首地址

mov edi,e
add edi,36
mov edi,[edi]
add edi,k 
mov ordinaladdress,edi ;导出序数表的首地址

invoke lenstr,addr szGetProcAddress
mov n,eax

;求GetProcAddress函数在文件中的位置
mov ebx,apinameaddress 
xor eax,eax
againke:push ebx
mov edi,[ebx]
add edi,k
mov esi,offset szGetProcAddress
mov ecx,n
repe cmpsb 
je nextke
pop ebx
add ebx,4
inc eax
jmp againke
nextke:add eax,ob;加上基数
mov i,eax
;求GetProcAddress函数的序数
mov eax,i
mov ebx,ordinaladdress
shl eax,1
add eax,ebx
movzx eax,word ptr [eax]
mov o,eax
;求GetProcAddress函数的地址
mov eax,o
sub eax,ob;减去基数

mov ebx,apiaddress
shl eax,2
add eax,ebx
mov eax,[eax]
add eax,k
mov f,eax
;求loadlibrary函数的地址
push offset szLoadLibrary
push k
call eax
mov ipapiloadlibrary,eax
;求user32.dll文件的地址
push offset szUser32
call ipapiloadlibrary
mov ipapiuser32,eax
;求MessageBox函数的地址
push offset szmessagebox
push ipapiuser32
call f
mov ipapimessagebox,eax
;显示一个信息
push 0
push offset correy
push offset correy
push 0
call ipapimessagebox
pop esp
ret
end start

  • 标 题:答复
  • 作 者:ufofind
  • 时 间:2010-05-22 14:40:41

.386
.model flat,stdcall
option casemap:none
include windows.inc
.code
start:
;############################################################得到kernel32模块基址
mov esi,[esp]                  ;
and esi,0ffff0000h                ;
.while TRUE                  ;
  .if word ptr [esi]==IMAGE_DOS_SIGNATURE          ;
    add esi,[esi+3ch]            ;
    .if word ptr [esi]==IMAGE_NT_SIGNATURE        ;
      .break              ;
    .endif                ;
  .endif                  ;
  sub esi,10000h                ;
  .break .if esi<07000000h            ;
.endw                ;7c800000  ;
;获取Kernel32.dll的基地址+0F0h;此时esi的指向的是NT_SIGNATURE      ;
;########################################################得到kernel32模块基址  ;






;########################################得到导出函数名字符串地址表的(数组起始RVA)
assume esi:ptr IMAGE_NT_HEADERS              ;
mov eax,[esi].OptionalHeader.DataDirectory.VirtualAddress      ;
add eax,esi                  ;
sub eax,0F0h                            ;得到导出表的地址      ;
assume eax:ptr IMAGE_EXPORT_DIRECTORY            ;
push eax                                ;得到导出表的地址      ;
mov eax,[eax].AddressOfNames              ;
mov edx,eax                  ;
add edx,esi                  ;
sub edx,0F0h                            ;导出函数名字符串地址表的(数组起始RVA)  ;
jmp a0                    ;
;########################################得到导出函数名字符串地址表的(数组起始RVA)






;##########################################################得到LoadLibraryA的地址
LoadLibrary db "LoadLibraryA",0              ;
a0:call @F                  ;
@@:                    ;
pop ebx                    ;
sub ebx,offset @B                ;
add ebx,offset LoadLibrary              ;
mov edi,ebx                  ;
mov ebx,edi                  ;
mov ecx,-1                    ;表示最从大开始扫描        ;
xor al,al                  ;
cld                    ;
repnz scasb                  ;
mov ecx,edi                  ;
sub ecx,ebx                   ;得到字符串的长度包括0        ;
sub edi,ecx                   ;要比较的字符串基地址        ;
push edx                  ;
xor eax,eax                  ;
.repeat                    ;
  push esi                ;
  mov esi,[edx]                ;
  pop ebx                  ;
  push ebx                ;
  add esi,ebx                ;
  sub esi,0F0h                ;
  assume esi:ptr IMAGE_EXPORT_DIRECTORY          ;
  push edi                ;
  push ecx                ;
  repz cmpsb                ;
  .if zero?                ;
    pop ecx                ;
    pop edi                ;
    pop esi                ;
    jmp @F                ;
  .endif                  ;
  pop ecx                  ;
  pop edi                  ;
  pop esi                  ;
  add edx,4                ;
  inc eax                  ;
.until eax>=[esi].NumberOfNames              ;
@@:                    ;
pop ebx                      ;导出函数名字符串地址表的(数组起始RVA)    ;
pop ecx                      ;得到导出表的地址          ;
push ecx                     ;得到导出表的地址          ;
push ebx                     ;导出函数名字符串地址表的(数组起始RVA)    ;
assume ecx:ptr IMAGE_EXPORT_DIRECTORY            ;
sub edx, esi                  ;
add edx,0F0h                  ;
sub edx,[ecx].AddressOfNames              ;
shr edx,1                    ;进行除以2            ;
add edx,[ecx].AddressOfNameOrdinals            ;
add edx,esi                  ;
sub edx,0F0h                  ;
movzx eax,word ptr [edx]     ;得到序号索引          ;
shl eax,2                    ;进行剩以2得到          ;
add eax,[ecx].AddressOfFunctions            ;
add eax,esi                  ;
sub eax,0F0h                  ;
mov eax,dword ptr [eax]                ;
add eax,esi                  ;
sub eax,0F0h                 ;得到LoadLibraryA的地址,为7c801D7B      ;
jmp a1                    ;
;##########################################################得到LoadLibraryA的地址



;##########################################################装入ntdll.dll##3####  ;
ntdll  db "ntdll.dll",0                ;
a1:call @F                  ;
@@:                    ;
pop ebx                    ;
sub ebx,offset @B                ;
add ebx,offset ntdll                ;
mov edi,ebx                  ;
push edi                  ;
call eax                     ;得到ntdll.dll的句柄7c9200000      ;
pop edx                      ;导出函数名字符串地址表的(数组起始RVA)    ;
push eax                             ;
jmp a2                    ;
;##########################################################装入ntdll.dll#######  ;


;##########################################################得到GetProcAddress的地址
GetProcAddress db "GetProcAddress",0            ;
a2:call @F                  ;
@@:                    ;
pop ebx                    ;
sub ebx,offset @B                ;
add ebx,offset GetProcAddress              ;
mov edi,ebx                  ;
mov ebx,edi                  ;
mov ecx,-1                   ;表示最从大开始扫描        ;
xor al,al                  ;
cld                    ;
repnz scasb                  ;
mov ecx,edi                  ;
sub ecx,ebx                  ;得到字符串的长度包括0        ;
sub edi,ecx                  ;要比较的字符串基地址        ;
xor eax,eax                  ;
.repeat                    ;
  push esi                ;
  mov esi,[edx]                ;
  pop ebx                  ;
  push ebx                ;
  add esi,ebx                ;
  sub esi,0F0h                ;
  push edi                ;
  push ecx                ;
  repz cmpsb                ;
  .if zero?                ;
    pop ecx                ;
    pop edi                ;
    pop esi                ;
    jmp @F                ;
  .endif                  ;
  pop ecx                  ;
  pop edi                  ;
  pop esi                  ;
  add edx,4                ;
  inc eax                  ;
.until eax>=[esi].NumberOfNames              ;
@@:                    ;
pop ebx                     ;得到ntdll.dll的句柄        ;
pop ecx                     ;得到导出表的地址          ;
push ebx                    ;得到ntdll.dll的句柄        ;
assume ecx:ptr IMAGE_EXPORT_DIRECTORY            ;
sub edx, esi                  ;
add edx,0F0h                  ;
sub edx,[ecx].AddressOfNames              ;
shr edx,1                   ;进行除以2            ;
add edx,[ecx].AddressOfNameOrdinals            ;
add edx,esi                  ;
sub edx,0F0h                  ;
movzx eax,word ptr [edx]    ;得到序号索引          ;
shl eax,2                  ;
add eax,[ecx].AddressOfFunctions            ;
add eax,esi                  ;
sub eax,0F0h                  ;
mov eax,dword ptr [eax]                ;
add eax,esi                  ;
sub eax,0F0h                ;得到GetProcAddress的地址7c80ae30      ;
push eax                  ;
jmp a3                    ;
;##########################################################得到GetProcAddress的地址




;##########################################################用GetProcAddress获取ntdll.dll模块内RtlAdjustPrivilege函数地址
RtlAdjustPrivilege  db "RtlAdjustPrivilege",0          ;
a3:call @F                  ;
@@:                    ;
pop ebx                    ;
sub ebx,offset @B                ;
add ebx,offset RtlAdjustPrivilege            ;
mov edi,ebx                   ;
                    ;
pop eax                    ;
pop ebx                    ;
push ebx                  ;
push eax                  ;
                    ;
                    ;
push edi                  ;
push ebx                                  ;ntdll.dll的模块基地址      ;
call eax                                  ;GetProcAddress的地址      ;
;##########################################################用GetProcAddress获取ntdll.dll模块内RtlAdjustPrivilege函数地址



push esp;得到RtlAdjustPrivilege的地址7C949A4D
push 0
push 1
push 13h
call eax
jmp a4;


;##########################################################用GetProcAddress获取ntdll.dll模块内NtShutdownSystem函数地址
NtShutdownSystem db "NtShutdownSystem",0                       ;
a4:call @F                               ;
@@:                                 ;
pop ebx                                 ;
sub ebx,offset @B                             ;
add ebx,offset NtShutdownSystem                           ;
mov edi,ebx                                ;
pop eax;                 ;
add eax,30h                               ;
pop ebx                                 ;
push ebx                               ;
push eax                               ;
                                 ;
                                 ;
push edi                               ;
push ebx;ntdll.dll的模块地址                           ;
call eax;得到NtShutdownSystem的地址                                                                                  ;
;##########################################################用GetProcAddress获取ntdll.dll模块内NtShutdownSystem函数地址



push 1;0为关机,1为重启
call eax
end start