一、获取kernel32

通过 LDR 链表遍历dll,检查 BaseDllName.Buffer 的第6,7个字符是不是"32",如果是就认为是kernel32.

// CTF.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>int main()
{HMODULE hModule = 0;char lpszModuleFileName[MAX_PATH] = { 0 };// 按照加载顺序找dll,ntdll第一个加载,然后是kernel32(kernelbase)__asm{mov eax, fs: [0x30] ; // PEBmov eax, dword ptr[eax + 0x0c]; // PEB->PEB_LDR_DATAmov esi, dword ptr[eax + 0x1c]; // PLDR_DATA_TABLE_ENTRY->InInitializationOrderLinkssc_goonkernel:mov eax, dword ptr[esi + 0x8]; // &InInitializationOrderModuleList + 8 == &DllBasemov ebx, dword ptr[esi + 0x20]; // BaseDllName.Buffermov esi, dword ptr[esi];cmp dword ptr[ebx + 0xc], 0x00320033; // L"32"jnz sc_goonkernel;mov hModule, eax;}GetModuleFileNameA(hModule, lpszModuleFileName, MAX_PATH);printf("[%p] %s\n", hModule, lpszModuleFileName);system("pause");return 0;
}

如果希望更加精确,可以做更加详细的判断,比如匹配"l32.“或"L32.”,比较两次是因为32前面的L可能是大写或小写。

// CTF.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>int main()
{printf("%x %x\n", ((PDWORD)&L"L32.")[0], ((PDWORD)&L"L32.")[1]);printf("%x %x\n", ((PDWORD)&L"l32.")[0], ((PDWORD)&L"l32.")[1]);HMODULE hModule = 0;char lpszModuleFileName[MAX_PATH] = { 0 };// 按照加载顺序找dll,ntdll第一个加载,然后是kernel32(kernelbase)__asm{mov eax, fs: [0x30] ; // PEBmov eax, dword ptr[eax + 0x0c]; // PEB->PEB_LDR_DATAmov esi, dword ptr[eax + 0x1c]; // PLDR_DATA_TABLE_ENTRY->InInitializationOrderLinkssc_goonkernel:mov eax, dword ptr[esi + 0x8]; // &InInitializationOrderModuleList + 8 == &DllBasemov ebx, dword ptr[esi + 0x20]; // BaseDllName.Buffermov esi, dword ptr[esi];cmp dword ptr[ebx + 0xe], 0x002e0032; // L"2."jnz sc_goonkernel;cmp dword ptr[ebx + 0xa], 0x0033006c; // L"l3"        jz sc_foundkernel32;cmp dword ptr[ebx + 0xa], 0x0033004c; // L"L3"jnz sc_goonkernel;sc_foundkernel32:mov hModule, eax;}GetModuleFileNameA(hModule, lpszModuleFileName, MAX_PATH);printf("[%p] %s\n", hModule, lpszModuleFileName);system("pause");return 0;
}

二、获取 LoadLibraryA GetProcAddress

实现一个简单的hash计算方法,先算出这两个API的hash,然后遍历kernel32的导出表,通过计算函数名的hash来找函数地址。

 // Find LoadLibraryA and GetProcAddressPIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(hKernel32 +((PIMAGE_NT_HEADERS)(hKernel32 + ((PIMAGE_DOS_HEADER)hKernel32)->e_lfanew))->OptionalHeader.DataDirectory[0].VirtualAddress);PDWORD AddressOfFunctions = (PDWORD)(hKernel32 + pExportDirectory->AddressOfFunctions);PDWORD AddressOfNames = (PDWORD)(hKernel32 + pExportDirectory->AddressOfNames);PWORD AddressOfNameOridinals = (PWORD)(hKernel32 + pExportDirectory->AddressOfNameOrdinals);for (size_t i = 0; i < pExportDirectory->NumberOfNames; i++){char *FuncName = (char *)(hKernel32 + AddressOfNames[i]);char *p = FuncName;DWORD j = 0;DWORD hash = 1;DWORD len = 0;while (*p++)len++;while (len > 3 && j < len - 3){hash += ror(((PDWORD)FuncName)[j], 7);j++;}       if (0x388dd59d == hash){pGetProcAddress = (PGETPROCADDRESS)(AddressOfFunctions[AddressOfNameOridinals[i]] + hKernel32);// 388dd59d GetProcAddress}else if (0x5e591b27 == hash){pLoadLibraryA = (PLOADLIBRARYA)(AddressOfFunctions[AddressOfNameOridinals[i]] + hKernel32);// 5e591b27 LoadLibraryA}}

三、完整demo

测试一下获取到的api,弹出一个消息框。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>typedef HMODULE(WINAPI *PLOADLIBRARYA)(LPCSTR);
typedef DWORD(WINAPI *PGETPROCADDRESS)(HMODULE, LPCSTR);
#define ror(value, bits) ((value >> bits) | (value << (sizeof(value)*8 - bits)))int main()
{DWORD hKernel32 = 0xFFFFFFFF;PGETPROCADDRESS pGetProcAddress = NULL;PLOADLIBRARYA pLoadLibraryA = NULL;// Find kernel32__asm{mov eax, fs: [0x30] ; // PEBmov eax, dword ptr[eax + 0x0c]; // PEB->PEB_LDR_DATAmov esi, dword ptr[eax + 0x1c]; // PLDR_DATA_TABLE_ENTRY->InInitializationOrderLinkssc_goonkernel:mov eax, dword ptr[esi + 0x8]; // &InInitializationOrderModuleList + 8 == &DllBasemov ebx, dword ptr[esi + 0x20]; // BaseDllName.Buffermov esi, dword ptr[esi];cmp dword ptr[ebx + 0xe], 0x002e0032; // L"2."jnz sc_goonkernel;cmp dword ptr[ebx + 0xa], 0x0033006c; // L"l3"        jz sc_foundkernel32;cmp dword ptr[ebx + 0xa], 0x0033004c; // L"L3"jnz sc_goonkernel;sc_foundkernel32:mov hKernel32, eax;}// Find LoadLibraryA and GetProcAddressPIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(hKernel32 +((PIMAGE_NT_HEADERS)(hKernel32 + ((PIMAGE_DOS_HEADER)hKernel32)->e_lfanew))->OptionalHeader.DataDirectory[0].VirtualAddress);PDWORD AddressOfFunctions = (PDWORD)(hKernel32 + pExportDirectory->AddressOfFunctions);PDWORD AddressOfNames = (PDWORD)(hKernel32 + pExportDirectory->AddressOfNames);PWORD AddressOfNameOridinals = (PWORD)(hKernel32 + pExportDirectory->AddressOfNameOrdinals);for (size_t i = 0; i < pExportDirectory->NumberOfNames; i++){char *FuncName = (char *)(hKernel32 + AddressOfNames[i]);char *p = FuncName;DWORD j = 0;DWORD hash = 1;DWORD len = 0;while (*p++)len++;while (len > 3 && j < len - 3){hash += ror(((PDWORD)FuncName)[j], 7);j++;}        if (0x388dd59d == hash){pGetProcAddress = (PGETPROCADDRESS)(AddressOfFunctions[AddressOfNameOridinals[i]] + hKernel32);// 388dd59d GetProcAddress}else if (0x5e591b27 == hash){pLoadLibraryA = (PLOADLIBRARYA)(AddressOfFunctions[AddressOfNameOridinals[i]] + hKernel32);// 5e591b27 LoadLibraryA}}// testDWORD msgboxa = pGetProcAddress(pLoadLibraryA("user32.dll"), "MessageBoxA");((DWORD(WINAPI *)(DWORD, DWORD, DWORD, DWORD))msgboxa)(0, 0, 0, 0);system("pause");return 0;
}

shellcode模板(使用hash获取API)相关推荐

  1. php7抓取网页数据,php7-远程获取api接口或网页内容

    在各类项目中经常要用到API调用,或是抓取对方网页内容,这里给大家一个远程获取API接口的PHP函数,函数返回一个数组,$result[0]为状态码,正常情况下是200,$result[1]为正常返回 ...

  2. 如何从XMLHttpRequest创建自定义获取API

    What is your worst nightmare? 你最可怕的噩梦是什么? That sounded dark, but it's not a rhetorical question. I r ...

  3. ChatGPT 如何获取API Key

    什么是OpenAI API Key? OpenAI是ChatGPT的"开发商",提供API使得开发者可以在自己的应用程序上调用OpenAI的相关服务(除了ChatGPT,OpenA ...

  4. 微信公众号发红包需要的API证书是什么,如何获取API证书?

    原文地址:什么是API证书?如何获取API证书? 什么是API证书?如何获取API证书? 一.什么是API证书 1.技术开发人员在调用微信支付安全级别较高的接口(如:退款.企业红包.企业付款)时,会使 ...

  5. html使用thymeleaf模板时,获取数据库中字符串值,拆分为list根据下标获取对应的值的方法

    1. 需求 html使用thymeleaf模板时,获取数据库中字符串值,拆分为list根据下标获取对应的值的方法 2. 方法 2.1 参考官网:https://www.thymeleaf.org/do ...

  6. 电商平台订单获取API接口文档

    电商平台原始订单推送(不包含订单敏感信息) 描述 用于点三OMS向外部ERP推送电商平台原始订单信息,原始订单状态变化.地址变更.备注修改.旗帜变化.退款变化等都会触发推送. 电商平台订单获取API接 ...

  7. ajax获取api中json数据显示到网页【带有“-”横杠注意】

    ajax获取api中json数据显示到网页 JSON数据中 类如aaa-bbb  这个中间有横杠的正确写法 $(function(){$.ajax({url: 'https://api.xxx.com ...

  8. 必应(Bing)每日图片获取API

    必应(Bing)每日图片获取API January 11, 2015 API http://lab.dobyi.com/api/bing.php 介绍 Value Description title ...

  9. 微信小程序(三):使用template模板时无法获取for循环下标index的问题

    使用template模板渲染的数据列表,点击后跳转到详情页,本想通过for循环中的index对应点击的是哪一条数据,后来发现template模板中无法获取index. 问题重现:[接微信小程序(二)的 ...

最新文章

  1. php连接不到mysql怎么解决,怎么解决php无法连接mysql的问题
  2. 陶哲轩实分析习题17.1.2
  3. 基于OWL-S的Web服务质量本体的描述模式的设计(转)
  4. sendmessage和postmessage的区别
  5. 简单介绍日志的发展历史
  6. oracle怎么删除lob对象,Oracle系列:LOB大对象处理
  7. CAD/CAM/CNC行业常用功能解决方式
  8. Python音乐播放器-美观-简约-本地
  9. 【转载】大型网站性能
  10. Mac 查找本机的ip
  11. 更换根目录linux命令,linux中怎么切换到根目录
  12. Python模块之Shapely
  13. EOS区块链PHP开发包
  14. 本田及通用公司利用区块链技术探索智能电网与电动汽车的互操作性
  15. Python实现截图?一文带你入门
  16. 基于MATLAB的人民币识别系统
  17. [agc004e]Salvage Robots
  18. 编程练习题 没答案版
  19. jquery.chained与jquery.chained.remote使用以及区别
  20. SpringMVC项目升级SpringBoot项目参考

热门文章

  1. AI:2020 科大讯飞AI开发者大赛,总奖金池180+万元!拿下比赛,大厂offer到手,那么,你还在等什么?
  2. 成功解决AttributeError: module 'tensorflow.nn.rnn_cell' has no attribute 'linear'
  3. 成功解决AttributeError: module 'numpy' has no attribute 'integer'
  4. 成功解决ValueError: Found input variables with inconsistent numbers of samples: [86, 891]
  5. ML之PLiR之LARS:利用LARS算法求解ElasticNet回归类型(包括类别编码+属性重要程度排序)问题(实数值年龄预测)
  6. Py之pyecharts:基于大数据对人工智能进行各种可视化图表分析
  7. 成功解决如何去掉输出字典,前边的dict_keys
  8. RBF:RBF基于近红外光谱的汽油辛烷值含量预测结果对比
  9. 蓝桥杯_算法训练_动态数组使用
  10. 多边形填充算法-有序边表法(扫描线算法) 计算机图形学