实际上,这块可以写成汇编,然后做远程注入用

方法

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获取指定模块基址的更多相关文章

  1. 如何调用写好的指定模块?——sys.path

    python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...

  2. 旧书重温:0day2【2】 实验:三种获取kernel32.dll基址的方法

    0x01 找kernel32基地址的方法一般有三种: 暴力搜索法.异常处理链表搜索法.PEB法. 0x02 基本原理 暴力搜索法是最早的动态查找kernel32基地址的方法.它的原理是几乎所有的win ...

  3. WinAPI: GetClassName - 获取指定窗口的类名

    WinAPI: GetClassName - 获取指定窗口的类名 //声明: GetClassName( hWnd: HWND; {指定窗口句柄} lpClassName: PChar; {缓冲区} ...

  4. Python获取指定文件夹下的文件名

    本文采用os.walk()和os.listdir()两种方法,获取指定文件夹下的文件名. 一.os.walk() 模块os中的walk()函数可以遍历文件夹下所有的文件. os.walk(top, t ...

  5. Python获取指定目录下所有子目录、所有文件名

    需求 给出制定目录,通过Python获取指定目录下的所有子目录,所有(子目录下)文件名: 实现 import os def file_name(file_dir): for root, dirs, f ...

  6. javascript怎么获取指定url网页中的内容

    javascript怎么获取指定url网页中的内容 一.总结 一句话总结:推荐jquery中ajax,简单方便. 1.js能跨域操作么? javascript出于安全机制不允许跨域操作的. 二.用ph ...

  7. kernel 获取ntoskrnl.exe基址

    标题: kernel shellcode之寻找ntoskrnl.exe基址 http://scz.617.cn:8/windows/201704171416.txt 以64-bits为例,这是Eter ...

  8. PyQt(Python+Qt)学习随笔:QTableWidget的获取指定位置项的item和itemAt方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.获取指定行和列的项 根据行和列可以获取对应位置的项,调用语法如下: QTableWidgetIt ...

  9. 如何通过源生js获取一个元素的具体样式值 /* getCss:获取指定元素的具体样式的属性值 curElement:[dom对象] attr:[string] */

    昨天的博客些的真的是惨不忍睹啊!!!但是我的人生宗旨就是将不要脸的精神进行到底,所以,今天我又来了.哈哈哈哈哈! 方法一:元素.style.属性名:(这个有局限性--只能获取行内样式的值,对于样式表或 ...

随机推荐

  1. 10、TestNG 的 FixTrue用法一

    Fixture 是指一个测试运行所需的固定环境,通俗来说 ,为测试用例所准备的环境. 以下是TestNG中可用的注释及其属性的简要概述. 我们先演示@BeforeClass.@AfterClass.@ ...

  2. 剑指offer第二版面试题1:数组中重复的数字(JAVA版)

    题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数.请找出数组中任意一个重复的数字.例如如果输入长度为7的数组{ ...

  3. 回退ios版本

    https://ipsw.me/ 访问以上网址,选择自己对应的手机,选择可下载的版本数据,打开itunes,自动备份数据,然后按住alt+左键点击恢复... 成功后. 然后进行备份自己的之前备份的数据 ...

  4. 【转载】Spring 源码分析之 bean 实例化原理

    本次主要想写spring bean的实例化相关的内容.创建spring bean 实例是spring bean 生命周期的第一阶段.bean 的生命周期主要有如下几个步骤: 创建bean的实例 给实例 ...

  5. Webpack4篇

    [Webpack4篇] webpack4 打包优化策略 当前依赖包的版本 1 优化loader配置 1.1 缩小文件匹配范围(include/exclude) 通过排除node_modules下的文件 ...

  6. 通过start.spring.io生成的springboot项目,导入IDE后POM第一行报错

    通过problem控制台查看,显示unknown 尝试降低springboot版本,问题没了,应该是与maven jdk等版本冲突导致 这里JDK 1.8  mave 3.6.1  降低springb ...

  7. spring的组成模块

    spring的核心组件(骨骼架构)——   共同创建了Bean关系网络 Core:主要定义了资源的访问方式 Context:给spring提供一个运行时的环境 Bean:Bean的定义,创建以及解析 ...

  8. React简单入门

    各位圆友,新年好!!! 使用 React 的网页源码时,首先,最后一个 <script> 标签的 type 属性为 text/babel .这是因为 React 独有的 JSX 语法,跟 ...

  9. egrep 或与

    ' HEADERABC' .txt | .txt 'HEADERABC' .txt > .txt .txt > .txt ' HEADERABC' ' TAILER123' .txt &g ...

  10. 初识webSocket及其使用

    阅读目录 1.什么是webSocket? 2.webSocket实现原理 3.webSocket优点 4.webSocket和socket的区别 5.webSocket API 6.webSocket ...