_asm
{
push ebp
mov eax,fs:[30h];获得PEB地址
mov eax,[eax+0ch];获得LDR地址
mov eax,[eax+14h];获得PEB_LDR_DATA中InMemoryOrderModuleList的
Flink
mov ecx,eax;因为eax中的Flink也就是等于LDR_DATA_TABLE_ENTRY中
InMemoryOrderLinks的Flink
sub eax,8;获得LDR_DATA_TABLE_ENTRY地址
;查看第一个入口点
mov eax,[eax+1ch];成功
;恢复eax中的Flink获得下一个Flink
mov eax,ecx
;获得下一个Flink
mov eax,[eax]
;保存Flink
mov ecx,eax
;获得第二个模块的入口点
sub eax,8
mov eax,[eax+1ch]
;恢复eax的Flink
mov EAX,ECX
;获得下一个Flink
mov eax,[eax]
;保存Flink
mov ecx,eax
;获得第三个模块的入口点,即kernel32
sub eax,8h
mov eax,[eax+1Ch]
;恢复eax的Flink
mov eax,ecx
;获得下一个Flink
mov eax,[eax]
;保存Flink
mov ecx,eax
;获得第四个模块的入口点
sub eax,8
mov eax,[eax+1ch]
;恢复eax的Flink
mov eax,ecx
;获得下一个Flink
mov eax,[eax]
;保存Flink
mov ecx,eax
;获得第五个模块的基地址,即user32.dll
sub eax,8
mov eax,[eax+18h]
;保存user32的基址
mov ebp,eax
;PE头部
mov eax,[ebp+3ch]
;输出表偏移
mov edx,[ebp+eax+78h]
;输出表地址
add edx,ebp
;输出函数个数
mov ecx,[edx+18h];正确
;获得AddressOfNamesRVA
mov ebx,[edx+20h]
;获得AddressOfNames地址
add ebx,ebp
search:
dec ecx
mov esi,[ebx+ecx*4]
;获得函数名称
add esi,ebp
mov eax,0x7373654D;'sseM'
cmp [esi],eax
jne search;
mov eax,0x42656761;'Bega'
cmp [esi+4],eax
jne search
mov eax,0x0041786F;'_Axo'
cmp [esi+8],eax
jne search
;找到MessageBoxA,获取函数需要偏移地址
;函数序号数组偏移地址
mov ebx,[edx+24h]
add ebx,ebp
;计算出序号值
mov cx,[ebx+ecx*2]
;获得函数地址数组指针
mov ebx,[edx+1ch]
add ebx,ebp
;获得函数偏移量
mov eax,[ebx+ecx*4]
add eax,ebp;//得到MessageBoxA的地址
;数据定义
data:
;显示的数据在新加段中显示
lea ebx,data
PUSH 0
PUSH 0
PUSH 0
PUSH 0
call eax
pop ebp
}
获取LoadLibrary的地址
// tmp.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include<ImageHlp.h>
#pragma comment(lib,"imagehlp.lib")
using namespace std;
int main()
{
//;关于IMAGE_EXPORT_DIRECTORY中的地址变量在使用时都要加上IMAGE_EXPORT_DIRECTORY的基地址
_asm
{
push ebp;暂存基址
mov eax,fs:[30h];获取PEB地址
mov eax,[eax+0ch];获取LDR地址
mov eax,[eax+14h];获得PEB_LDR_DATA中InMemoryOrderModuleListFlink的地址,该地址和LDR_DATA_TABLE_ENTRY中的Flink相同
;保存Flink
mov ecx,eax
;获取LDR_DATA_TABLE_ENTRY的基址
sub eax,8
;获得该模块的基址,第一个模块应该是其自身
mov eax,[eax+18h];成功
;恢复eax中的Flink
mov eax,ecx
;获取下一个Flink
mov eax,[eax]
;保存该Flink
mov ecx,eax
;获取第二个模块的基址一般是ntdll
sub eax,8
mov eax,[eax+18h]
;恢复eax中的Flink
mov eax,ecx
;获取第三个模块的Flink,一般是kernel32.dll
mov eax,[eax]
;保存当前Flink
mov ecx,eax
;获取该模块的基址
sub eax,8
mov eax,[eax+18h];到此已经得到了我们需要的kernel32.dll的基址
;ebp保存dll的基址
mov ebp,eax
;获取PE头部
mov eax,[ebp+3Ch]
;获取导出表头部偏移量
mov edx,[ebp+eax+78h]
;获取输出表地址edx
add edx,ebp
;获得输出函数个数
mov ecx,[edx+18h];正确
;获取输出函数名称数组地址,放在ebx当中
mov ebx,[edx+20h]
add ebx,ebp
search:
dec ecx;
mov esi,[ebx+ecx*4]
add esi,ebp;
mov eax,64616f4ch;'daoL'
cmp eax,[esi]
jnz search
mov eax,7262694ch;'rbiL'
;mov eax,49707071h
cmp eax,[esi+4]
jnz search
mov eax,41797261h;'Ayra'
cmp eax,[esi+8]
jnz search
;找到了函数名也就是,有了序号
;再获取函数序号数组地址
mov ebx,[edx+24h]
add ebx,ebp
;得出函数序号注意:函数序号是一个字变量
mov cx,[ebx+ecx*2]
;获取函数地址数组地址
mov ebx,[edx+1ch]
add ebx,ebp
;根据序号取出函数地址
mov eax,[ebx+ecx*4]
add eax,ebp
push 0
call eax;
pop ebp
}
return 0;
}
标签:ebx,Flink,地址,mov,eax,MessageBoxA,ebp,shellcode,ecx
From: https://blog.51cto.com/u_15995156/6166924