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

方法

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成员信息。

  1. #include <windows.h>
  2.  
  3. #define CONTAINING_RECORD(address, type, field) ((type *)( (PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
  4.  
  5. typedef struct _UNICODE_STRING {
  6. USHORT Length;
  7. USHORT MaximumLength;
  8. PWSTR Buffer;
  9. } UNICODE_STRING, *PUNICODE_STRING;
  10.  
  11. typedef struct _PEB_LDR_DATA
  12. {
  13. DWORD Length;
  14. UCHAR Initialized;
  15. PVOID SsHandle;
  16. LIST_ENTRY InLoadOrderModuleList;
  17. LIST_ENTRY InMemoryOrderModuleList;
  18. LIST_ENTRY InInitializationOrderModuleList;
  19. PVOID EntryInProgress;
  20. }PEB_LDR_DATA,*PPEB_LDR_DATA;
  21.  
  22. typedef struct _LDR_DATA_TABLE_ENTRY
  23. {
  24. LIST_ENTRY InLoadOrderLinks;
  25. LIST_ENTRY InMemoryOrderLinks;
  26. LIST_ENTRY InInitializationOrderLinks;
  27. PVOID DllBase;
  28. PVOID EntryPoint;
  29. DWORD SizeOfImage;
  30. UNICODE_STRING FullDllName;
  31. UNICODE_STRING BaseDllName;
  32. DWORD Flags;
  33. WORD LoadCount;
  34. WORD TlsIndex;
  35. LIST_ENTRY HashLinks;
  36. PVOID SectionPointer;
  37. DWORD CheckSum;
  38. DWORD TimeDateStamp;
  39. PVOID LoadedImports;
  40. PVOID EntryPointActivationContext;
  41. PVOID PatchInformation;
  42. }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
  43.  
  44. typedef struct _PEB
  45. {
  46. UCHAR InheritedAddressSpace;
  47. UCHAR ReadImageFileExecOptions;
  48. UCHAR BeingDebugged;
  49. UCHAR SpareBool;
  50. PVOID Mutant;
  51. PVOID ImageBaseAddress;
  52. PPEB_LDR_DATA Ldr;
  53. }PEB,*PPEB;
  54.  
  55. int main(void)
  56. {
  57. PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;
  58. PLIST_ENTRY pListEntryStart = NULL,pListEntryEnd = NULL;
  59. PPEB_LDR_DATA pPebLdrData = NULL;
  60. PPEB pPeb = NULL;
  61.  
  62. __asm
  63. {
  64. //1、通过fs:[30h]获取当前进程的_PEB结构
  65. mov eax,dword ptr fs:[30h];
  66. mov pPeb,eax
  67. }
  68.  
  69. //2、通过_PEB的Ldr成员获取_PEB_LDR_DATA结构
  70. pPebLdrData = pPeb->Ldr;
  71.  
  72. //3、通过_PEB_LDR_DATA的InMemoryOrderModuleList成员获取_LIST_ENTRY结构
  73. pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;
  74.  
  75. //查找所有已载入到内存中的模块
  76. do
  77. {
  78. //4、通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构
  79. pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks);
  80.  
  81. //5、输出_LDR_DATA_TABLE_ENTRY的BaseDllName或FullDllName成员信息
  82. printf("%S\n",pLdrDataEntry->BaseDllName.Buffer);
  83.  
  84. pListEntryStart = pListEntryStart->Flink;
  85.  
  86. }while(pListEntryStart != pListEntryEnd);
  87.  
  88. return ;
  89. }

注入相关的代码在这里

  1. #include <Windows.h>
  2.  
  3. #include <stdio.h>
  4.  
  5. typedef struct _UNICODE_STRING {
  6. USHORT Length;
  7. USHORT MaximumLength;
  8. PWCH Buffer;
  9. } UNICODE_STRING;
  10.  
  11. typedef struct _LDR_DATA_TABLE_ENTRY
  12. {
  13. LIST_ENTRY InLoadOrderLinks;
  14. LIST_ENTRY InMemoryOrderLinks;
  15. LIST_ENTRY InInitializationOrderLinks;
  16. PVOID DllBase;
  17. PVOID EntryPoint;
  18. ULONG SizeOfImage;
  19. UNICODE_STRING FullDllName;
  20. UNICODE_STRING BaseDllName;
  21. ULONG Flags;
  22. WORD LoadCount;
  23. WORD TlsIndex;
  24. union
  25. {
  26. LIST_ENTRY HashLinks;
  27. struct
  28. {
  29. PVOID SectionPointer;
  30. ULONG CheckSum;
  31. };
  32. };
  33. union
  34. {
  35. ULONG TimeDateStamp;
  36. PVOID LoadedImports;
  37. };
  38. void * EntryPointActivationContext;
  39. PVOID PatchInformation;
  40. LIST_ENTRY ForwarderLinks;
  41. LIST_ENTRY ServiceTagLinks;
  42. LIST_ENTRY StaticLinks;
  43. } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
  44.  
  45. // 把一个字符串做成一个 hash 值
  46. __declspec(naked) DWORD __stdcall HashString( WCHAR *name )
  47. {
  48. __asm
  49. {
  50. push esi;
  51. push edi;
  52. mov esi , [esp + 0x0C];
  53. xor edi , edi;
  54. cld;
  55. __iter:
  56. xor eax , eax;
  57. lodsw ;
  58. cmp al , ah;
  59. je __done;
  60. ror edi , 0x0D;
  61. add edi ,eax ;
  62. jmp __iter;
  63. __done:
  64. mov eax , edi;
  65. pop edi;
  66. pop esi;
  67. retn ;
  68. }
  69. }
  70.  
  71. // 遍历 LDR 表,找到要找的 DLL 基址
  72. PVOID __stdcall GetDllBase( LIST_ENTRY *head , DWORD hash )
  73. {
  74. PLDR_DATA_TABLE_ENTRY t;
  75. LIST_ENTRY *p = head->Flink;
  76. for ( ; p != head ; p = p->Flink )
  77. {
  78. t = (PLDR_DATA_TABLE_ENTRY)((char*)p - 0x10);
  79. if ( hash == HashString( t->BaseDllName.Buffer ) )
  80. {
  81. return t->DllBase;
  82. }
  83. }
  84. return ;
  85. }
  86.  
  87. // 从 fs 段找到 TEB ,从 TEB 找到 PEB ,从 PEB 找到 LDR 表
  88. // 返回值为 LDR 表链的头节点
  89. __declspec(naked) LIST_ENTRY * __stdcall FindLDRTable()
  90. {
  91. __asm
  92. {
  93. push esi;
  94. xor eax , eax;
  95. mov eax , fs:[0x30];
  96. test eax , eax;
  97. js __k9x;
  98. mov eax , [eax + 0x0C];
  99. lea esi , [eax + 0x1C];
  100. mov eax , esi;
  101. jmp near __finish;
  102. __k9x:
  103. xor eax , eax;
  104. __finish:
  105. pop esi;
  106. ret;
  107. }
  108. }
  109.  
  110. // 获取一个已经加载了的模块地址
  111. // name 只是名字,不可以是路径带名字
  112. PVOID LoadLibraryIn( WCHAR *name )
  113. {
  114. return GetDllBase( FindLDRTable() , HashString( name ) );
  115. }
  116.  
  117. int main()
  118. {
  119. //printf("0x%p\n" , HashString(L"kernel32.dll"));
  120. //printf("0x%p\n" , HashString(L"User32.dll"));
  121.  
  122. printf( "0x%p \n" , LoadLibraryIn( L"kernel32.dll" ) );
  123. printf( "0x%p \n" , LoadLibraryA( "kernel32.dll" ) );
  124. printf( "0x%p \n" , LoadLibraryA( "ntdll.dll" ) );
  125.  
  126. return ;
  127. }

用汇编来做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. 搭建hadoop集群 单机版

    二.在Ubuntu下创建hadoop用户组和用户         这里考虑的是以后涉及到hadoop应用时,专门用该用户操作.用户组名和用户名都设为:hadoop.可以理解为该hadoop用户是属于一 ...

  2. 拾遗:YouCompleteMe 前传——编译安装 llvm + clang

    http://llvm.org/docs/GettingStarted.html 一.下载安装 cmake >=3.4.3 yum install gcc gcc-c++curl -O http ...

  3. js实现禁止页面拖拽图片

    document.ondragstart = function() {        return false;};

  4. MFS分布式文件系统【3】存储节点 CHUNK SERVER 部署

    [root@ky_hs_252 mfs-1.6.27]# mkdir /usr/local/mfs [root@ky_hs_252 mfs-1.6.27]# useradd mfs -s /sbin/ ...

  5. 自从阿里买了Flink母公司以后,你不懂Flink就out了!

    个免费报名权限 Ps:小助理手动给大家发送资料,精力有限,仅限前100名免费领取,这份资料对于想要提升大数据技能进阶的小伙伴来说,将会是一份不可或缺的宝贵资料. 特别感谢飞总的部分原创支持!

  6. 为什么Netty这么火?与Mina相比有什么优势?

    Netty是什么?为什么这么火? Netty是目前最流行的由JBOSS提供的一个Java开源框架NIO框架,Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服 ...

  7. eduCF#61 C. Painting the Fence /// DP 选取k段能覆盖的格数

    题目大意: 给定n m 接下来给定m个在n范围内的段的左右端 l r 求选取m-2段 最多能覆盖多少格 #include <bits/stdc++.h> using namespace s ...

  8. 操作bin目录下的文件

    string dir = AppDomain.CurrentDomain.BaseDirectory + "Video"; if (!System.IO.Directory.Exi ...

  9. CSIC_716_20191203【 socket网络编程,以及沾包问题的高级解决方式】

    AF_UNIX(本机通信) AF_INET(TCP/IP – IPv4) AF_INET6(TCP/IP – IPv6) SOCK_STREAM(TCP流) SOCK_DGRAM(UDP数据报) 远程 ...

  10. Java 导出excel进行换行

    在导出excel 的时候,如果原始文字中含有 \n 字符,生成的excel中 会生成 _0040_ 字样的乱码, 如果把 \n 替换为<br/>,excel不会识别成换行符 excel 认 ...