能力值:
( LV2,RANK:10 )
|
-
-
2 楼
你这是什么平台下面的,不同平台,函数入口地址偏移量未必相同,我看你的偏移量都是写死的
|
能力值:
( LV9,RANK:210 )
|
-
-
3 楼
我以前写的一个查找kernel32.dll基址,并根据名称查找函数地址的ShellCode,已经注释得很清楚了,XP和WIN7通用
jmp ShellCodeStart
Addr_IAT_LoadLibraryA dd 402000h ;LoadLibraryA在IAT中的地址,由注入函数写入
Addr_LoadLibraryA dd 7C801D77h ;LoadLibraryA的地址,由注入函数写入,在ShellCode + 2 + 4处
Addr_VirtualProtectName db "VirtualProtect",0 ;VirtualProtect名称的地址
Addr_LoadDllName db "InputDll.dll",0
ShellCodeStart:
push ebx
push ecx
push edx
push esi
push edi
push ebp
xor ecx, ecx ;查找kernel32.dll基址放入eax,xor ecx, ecx不可丢
assume fs:nothing
mov esi, fs:[30h] ;取PEB
mov esi, [esi+0Ch]
mov esi, [esi+1Ch]
InInitializationOrderModuleList:
mov eax, ds:[esi+8]
mov edi, ds:[esi+20h]
mov esi, ds:[esi]
cmp WORD ptr ds:[edi+18h],cx
jnz InInitializationOrderModuleList
push ebp
call RelocLocation ;push eip,eip = 新RelocLocation的地址
RelocLocation:
pop ebp ;将eip出栈给ebp,ebp = 新RelocLocation的地址
sub ebp, offset RelocLocation ;ebp = ebp - offset RelocLocation(原RelocLocation地址)= 新旧地址的差值(参考重定位),后续需重定位的地址 = 原地址 + ebp
mov ecx, ebp ;取Addr_VirtualProtectName重定位后的地址并压栈
add ecx, offset Addr_VirtualProtectName
invoke GetAPI, eax, ecx, 14 ;调用GetAPI获取VirtualProtect的地址
mov ebx, eax ;将获取的地址放入ebx中
mov eax, ebp ;取Addr_LoadDllName重定位后的地址并压栈
add eax, offset Addr_LoadDllName
push eax
lea esi, [ebp + Addr_LoadLibraryA] ;取Addr_LoadLibraryA重定位后的地址,并调用LoadLibraryA
call DWORD ptr [esi] ;API为stdcall调用,自平衡堆栈
mov edi, [ebp + Addr_IAT_LoadLibraryA] ;取LoadLibraryA在IAT的地址
push eax ;随便压栈一个数,我们要用这个数的地址作为VirtualProtect的lpflOldProtect的地址,因为ShellCode的代码段不可写,只能用堆栈返回
push esp ;调用VirtualProtect修改IAT的写保护
push PAGE_READWRITE
push 4
push edi
call ebx
pop eax
mov eax, [esi] ;[esi] = LoadLibraryA的地址
mov [edi], eax ;将LoadLibraryA在IAT的地址改为IDHookLoadLibraryA的地址
pop ebp ;平衡
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
jmp eax ;跳转至LoadLibraryA继续执行
GetAPI proc _Kernel32Base:DWORD, _szAPIName:DWORD, _APINameLength:DWORD
local @SizeOfFNT:DWORD
local @APIAddr:DWORD
pushad
mov ebx, _Kernel32Base
assume ebx:ptr IMAGE_DOS_HEADER
add ebx, [ebx].e_lfanew ;取PE的首地址,即PE标志位
assume ebx:ptr IMAGE_NT_HEADERS
mov ebx, [ebx].OptionalHeader.DataDirectory.VirtualAddress
add ebx, _Kernel32Base
assume ebx:ptr IMAGE_EXPORT_DIRECTORY
mov eax, [ebx].NumberOfNames ;将函数总数乘以4,得FNT表大小
shl eax, 2
mov @SizeOfFNT, eax
mov edi, [ebx].AddressOfNames ;获取输出表API名称查询表(FNT)RVA
add edi, _Kernel32Base ;获取输出表API名称查询表(FNT)内存地址
mov esi, _szAPIName
mov ecx, _APINameLength
xor edx, edx
xor eax, eax ;eax置0
.while edx < @SizeOfFNT ;遍历Dll所有函数名称,当计数edx=Dll函数总数时退出循环
push ecx ;保存字符串长度
push edi ;保存edi,比较API名称
push esi
mov edi, [edi] ;取API名称的RVA
add edi, _Kernel32Base ;取API名称的内存地址
cld
repe cmpsb
pop esi ;将esi重新指向_szAPIName首地址
pop edi
pop ecx
jnz FAA_FindExportAPIAddr_NoFind ;如果ecx=0,说明函数字符全部相同
mov eax, [ebx].AddressOfFunctions ;取FAT表RVA
add eax, _Kernel32Base ;取FAT表RVA内存地址
add eax, edx ;取查找函数FAT表项的地址
mov eax, [eax] ;取查找函数的RVA
add eax, _Kernel32Base ;取查找函数的内存地址
mov @APIAddr, eax
.break ;找到则退出循环
FAA_FindExportAPIAddr_NoFind:
add edx, 4 ;计数+4指向下一个FNT表项
add edi, 4 ;edi指向下一个FNT表项
.endw
assume ebx:nothing
popad
mov eax, @APIAddr
ret
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
win7下的 我本机调试都通过不了,不知道什么原因= = 求解答 谢谢您
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
首先,谢谢您! 其实我想知道我这个为什么错了= = 还希望能麻烦您稍微点拨一下
|
能力值:
( LV5,RANK:70 )
|
-
-
6 楼
没用ShellExecute?没用Shell32这个dll?
|