无LoadLibrary获取指定模块基址
实际上,这块可以写成汇编,然后做远程注入用
方法
1、通过fs:[30h]获取当前进程的_PEB结构
2、通过_PEB的Ldr成员获取_PEB_LDR_DATA结构
3、通过_PEB_LDR_DATA的InMemoryOrderModuleList成员获取_LIST_ENTRY结构
4、通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构,注意:这里的Flink指向的是_LDR_DATA_TABLE_ENTRY结构中的InMemoryOrderLinks成员,因此需要计算真正的_LDR_DATA_TABLE_ENTRY起始地址,我们可以用CONTAINING_RECORD来计算。
5、输出_LDR_DATA_TABLE_ENTRY的BaseDllName或FullDllName成员信息。
#include <windows.h> #define CONTAINING_RECORD(address, type, field) ((type *)( (PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field))) typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING; typedef struct _PEB_LDR_DATA
{
DWORD Length;
UCHAR Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
}PEB_LDR_DATA,*PPEB_LDR_DATA; typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
DWORD SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
DWORD Flags;
WORD LoadCount;
WORD TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
DWORD CheckSum;
DWORD TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY; typedef struct _PEB
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR SpareBool;
PVOID Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
}PEB,*PPEB; int main(void)
{
PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;
PLIST_ENTRY pListEntryStart = NULL,pListEntryEnd = NULL;
PPEB_LDR_DATA pPebLdrData = NULL;
PPEB pPeb = NULL; __asm
{
//1、通过fs:[30h]获取当前进程的_PEB结构
mov eax,dword ptr fs:[30h];
mov pPeb,eax
} //2、通过_PEB的Ldr成员获取_PEB_LDR_DATA结构
pPebLdrData = pPeb->Ldr; //3、通过_PEB_LDR_DATA的InMemoryOrderModuleList成员获取_LIST_ENTRY结构
pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink; //查找所有已载入到内存中的模块
do
{
//4、通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构
pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks); //5、输出_LDR_DATA_TABLE_ENTRY的BaseDllName或FullDllName成员信息
printf("%S\n",pLdrDataEntry->BaseDllName.Buffer); pListEntryStart = pListEntryStart->Flink; }while(pListEntryStart != pListEntryEnd); return ;
}
注入相关的代码在这里
#include <Windows.h> #include <stdio.h> typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWCH Buffer;
} UNICODE_STRING; typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
void * EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; // 把一个字符串做成一个 hash 值
__declspec(naked) DWORD __stdcall HashString( WCHAR *name )
{
__asm
{
push esi;
push edi;
mov esi , [esp + 0x0C];
xor edi , edi;
cld;
__iter:
xor eax , eax;
lodsw ;
cmp al , ah;
je __done;
ror edi , 0x0D;
add edi ,eax ;
jmp __iter;
__done:
mov eax , edi;
pop edi;
pop esi;
retn ;
}
} // 遍历 LDR 表,找到要找的 DLL 基址
PVOID __stdcall GetDllBase( LIST_ENTRY *head , DWORD hash )
{
PLDR_DATA_TABLE_ENTRY t;
LIST_ENTRY *p = head->Flink;
for ( ; p != head ; p = p->Flink )
{
t = (PLDR_DATA_TABLE_ENTRY)((char*)p - 0x10);
if ( hash == HashString( t->BaseDllName.Buffer ) )
{
return t->DllBase;
}
}
return ;
} // 从 fs 段找到 TEB ,从 TEB 找到 PEB ,从 PEB 找到 LDR 表
// 返回值为 LDR 表链的头节点
__declspec(naked) LIST_ENTRY * __stdcall FindLDRTable()
{
__asm
{
push esi;
xor eax , eax;
mov eax , fs:[0x30];
test eax , eax;
js __k9x;
mov eax , [eax + 0x0C];
lea esi , [eax + 0x1C];
mov eax , esi;
jmp near __finish;
__k9x:
xor eax , eax;
__finish:
pop esi;
ret;
}
} // 获取一个已经加载了的模块地址
// name 只是名字,不可以是路径带名字
PVOID LoadLibraryIn( WCHAR *name )
{
return GetDllBase( FindLDRTable() , HashString( name ) );
} int main()
{
//printf("0x%p\n" , HashString(L"kernel32.dll"));
//printf("0x%p\n" , HashString(L"User32.dll")); printf( "0x%p \n" , LoadLibraryIn( L"kernel32.dll" ) );
printf( "0x%p \n" , LoadLibraryA( "kernel32.dll" ) );
printf( "0x%p \n" , LoadLibraryA( "ntdll.dll" ) ); return ;
}
用汇编来做3个关键函数,然后shellcode获取模块基址,计算PE,得到导出表,根据名称表找到对应的名字,地址表直接就能找到对应的函数地址了,
比较类似,自重定位,然后LoadLibrary GetProcAddress 了
无LoadLibrary获取指定模块基址的更多相关文章
- 如何调用写好的指定模块?——sys.path
python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...
- 旧书重温:0day2【2】 实验:三种获取kernel32.dll基址的方法
0x01 找kernel32基地址的方法一般有三种: 暴力搜索法.异常处理链表搜索法.PEB法. 0x02 基本原理 暴力搜索法是最早的动态查找kernel32基地址的方法.它的原理是几乎所有的win ...
- WinAPI: GetClassName - 获取指定窗口的类名
WinAPI: GetClassName - 获取指定窗口的类名 //声明: GetClassName( hWnd: HWND; {指定窗口句柄} lpClassName: PChar; {缓冲区} ...
- Python获取指定文件夹下的文件名
本文采用os.walk()和os.listdir()两种方法,获取指定文件夹下的文件名. 一.os.walk() 模块os中的walk()函数可以遍历文件夹下所有的文件. os.walk(top, t ...
- Python获取指定目录下所有子目录、所有文件名
需求 给出制定目录,通过Python获取指定目录下的所有子目录,所有(子目录下)文件名: 实现 import os def file_name(file_dir): for root, dirs, f ...
- javascript怎么获取指定url网页中的内容
javascript怎么获取指定url网页中的内容 一.总结 一句话总结:推荐jquery中ajax,简单方便. 1.js能跨域操作么? javascript出于安全机制不允许跨域操作的. 二.用ph ...
- kernel 获取ntoskrnl.exe基址
标题: kernel shellcode之寻找ntoskrnl.exe基址 http://scz.617.cn:8/windows/201704171416.txt 以64-bits为例,这是Eter ...
- PyQt(Python+Qt)学习随笔:QTableWidget的获取指定位置项的item和itemAt方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.获取指定行和列的项 根据行和列可以获取对应位置的项,调用语法如下: QTableWidgetIt ...
- 如何通过源生js获取一个元素的具体样式值 /* getCss:获取指定元素的具体样式的属性值 curElement:[dom对象] attr:[string] */
昨天的博客些的真的是惨不忍睹啊!!!但是我的人生宗旨就是将不要脸的精神进行到底,所以,今天我又来了.哈哈哈哈哈! 方法一:元素.style.属性名:(这个有局限性--只能获取行内样式的值,对于样式表或 ...
随机推荐
- 文件下载java代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...
- 2019杭电多校第三场hdu6609 Find the answer(线段树)
Find the answer 题目传送门 解题思路 要想变0的个数最少,显然是优先把大的变成0.所以离散化,建立一颗权值线段树,维护区间和与区间元素数量,假设至少减去k才能满足条件,查询大于等于k的 ...
- Codeforces 1173B Nauuo and Chess
题目链接:http://codeforces.com/problemset/problem/1173/B 思路参考:https://www.cnblogs.com/blowhail/p/1099123 ...
- HTML中改变列表的序号类型
HTML中,<ol>标签表示有序列表,每一个表项的编号默认从数字开始.比如 <html> <head> <title>test</title> ...
- 2019年Pandas官方用户调研
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline plt.rcP ...
- [已解决]报错JSONDecodeError
报错: 解决:
- python代码技巧总结(更新至17条)
怎么提高代码水平?答:看牛逼的代码! 牛逼的代码怎么写的?简单,明确,优雅! 怎么简单,明确,优雅?学技巧! 下面搜罗了一些有才格子褂青年的总结,哈哈 1.检查 Python 中的对象 调用 dir( ...
- Python 文件名
- [转]C# 动态调用 WebService
通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...
- 泛型(Generic)类的使用原因和使用方式
我们每个苹果都套个盒子,给每本书都套个盒子,但是苹果盒子和书盒子是不同的, 这样下去如果有更多的东西需要套盒子,1000种产品有1000种相应的盒子,造成类型极度膨胀非常难以维护. class Pro ...