首页 > 系统相关 >逆向 | shellcode注入模板

逆向 | shellcode注入模板

时间:2024-10-18 16:15:26浏览次数:1  
标签:逆向 dwKernel32Base index pLdrDataEntry LIST char ENTRY shellcode 模板

逆向 | shellcode注入模板

继续写书里的示例代码。

#include <stdio.h>
#include <windows.h>

typedef int (WINAPI* PMESSAGEBOXA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption, UINT uType);
typedef FARPROC (WINAPI* PGETPROCADDRESS)(HMODULE hModule,LPCSTR lpProcName);
typedef HMODULE (WINAPI* PLOADLIBRARY)(LPCTSTR lpFileName);
/*
typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;                  // 3个双向链表
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID      DllBase;
    PVOID      EntryPoint;
    UINT    SizeOfImage;               // 这里32位的就是UINT 64位是UINT64
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;     // 查找这个
	//...
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

void shellcode(){
	// 准备字符串备用
	// wchar_t wsKernel32Dll[] = L"kernel32.dll";
	char wsKernel32Dll[] = {'K', 0, 'E', 0, 'R', 0, 'N', 0, 'E', 0, 'L', 0, '3', 0, '2', 0, '.', 0, 'D', 0, 'L', 0, 'L', 0, 0, 0};
	char sUser32Dll[] = {'U', 'S', 'E', 'R', '3', '2', '.', 'd', 'l', 'l', 0};
	char sGetProcAddr[] = {'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', 0};
	char sLoadLibraryA[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0};
	char sMessageBoxA[] = {'M', 'e', 's', 's', 'a', 'g', 'e', 'B', 'o', 'x', 'A', 0};

	// 通过fs:[0x30]查找PEB 找到3个链表 找到K32.dll
	/*
	_PEB_LDR_DATA
	[0] Length
	[4] Initialized
	[8] SsHandle
	[c] InLoadOrderModuleList : _LIST_ENTRY
	[14] InMemoryOrderModuleList : _LIST_ENTRY
	[1c] InInitializationOrderModuleList : _LIST_ENTRY
	...

	*/
	DWORD pBeg = 0;
	DWORD pPLD = 0;
	PLIST_ENTRY pInLoadOrderModuleList = 0;
	__asm{
		pushad
		mov eax, fs:[0x30]        ; PEB
		mov eax, [eax+0x0c]       ; PEB->Ldr
		add eax, 0x0c             ; _PEB_LDR_DATA->InLoadOrderModuleList
		lea ebx, dword ptr [pInLoadOrderModuleList] ; 获取InLoadOrderModuleList的地址保存在变量中
		mov [ebx], eax;
		popad
	}
	//printf("InLoadOrderModuleList: %p %p \n",pInLoadOrderModuleList->Flink, pInLoadOrderModuleList->Blink);
	// 拿到第一个LDR_DATA_TABLE_ENTRY节点的地址
	PLDR_DATA_TABLE_ENTRY pFirstLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pInLoadOrderModuleList->Flink;
	// 循环遍历所有的模块 查找kernel32.dll
	DWORD dwKernel32Base = 0;
	PLDR_DATA_TABLE_ENTRY pLdrDataEntry = pFirstLdrDataEntry;
	while(1){
		//printf("[%p] %p %p \n", pLdrDataEntry, pLdrDataEntry->InLoadOrderLinks.Flink, pLdrDataEntry->InLoadOrderLinks.Blink);
		//printf("    [%S(%p)] %S \n", pLdrDataEntry->BaseDllName.Buffer, pLdrDataEntry->DllBase, pLdrDataEntry->FullDllName.Buffer);
		if (pLdrDataEntry->InLoadOrderLinks.Flink == (PLIST_ENTRY)pFirstLdrDataEntry){
			break;
		}
		// 判断是不是kernel32.dll
		/*
		if(wcsicmp(pLdrDataEntry->BaseDllName.Buffer, (wchar_t*)wsKernel32Dll) == 0){
			//printf("~~~~~~ find it! ~~~~~~~\n");
			dwKernel32Base = (DWORD)pLdrDataEntry->DllBase;
		}
		*/
		// 手动编写wcscmp
		wchar_t* wtmp = (wchar_t*)(pLdrDataEntry->BaseDllName.Buffer);
		int index = 0;
		int length = 0;
		while(((wchar_t*)wsKernel32Dll)[index] != 0){   // 计算长度
			index ++;
		}
		length = index;
		for (index = 0; index < length; index ++){      // 对比
			if (((wchar_t*)wsKernel32Dll)[index] != wtmp[index]){
				break;
			}
		}
		if (index == length){   // 找到了
			//puts("found");       // 找到kernel32.dll
			dwKernel32Base = (DWORD)pLdrDataEntry->DllBase;
		}

		pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataEntry->InLoadOrderLinks.Flink;
	}
	//printf("kernel32.dll base: %p \n", dwKernel32Base);  // 拿到kernel32.dll基址
	// 通过导出表查找LoadLibrary
	PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)dwKernel32Base;
	PIMAGE_NT_HEADERS pINHS = (PIMAGE_NT_HEADERS)(dwKernel32Base+pIDH->e_lfanew);
	PIMAGE_EXPORT_DIRECTORY pIED = (PIMAGE_EXPORT_DIRECTORY)(dwKernel32Base + pINHS->OptionalHeader.DataDirectory[0].VirtualAddress);
	DWORD* pAddressOfFunctions = (DWORD*)(dwKernel32Base + pIED->AddressOfFunctions);
	DWORD* pAddressOfNames = (DWORD*)(dwKernel32Base + pIED->AddressOfNames);
	WORD* pAddressOfNameOrdinals = (WORD*)(dwKernel32Base + pIED->AddressOfNameOrdinals);
	int i = 0;
	while(1){
		// printf("[%d] %s {%d} \n", i, dwKernel32Base+pAddressOfNames[i], pAddressOfNameOrdinals[i]);
		/*
		if (strcmp(sGetProcAddr, (char*)(dwKernel32Base + pAddressOfNames[i]))==0){
			//puts("found");       // 找到对应在序号表的第i个位置
			break;
		}
		*/
		// 手动编写strcmp
		char* tmp = (char*)(dwKernel32Base + pAddressOfNames[i]);
		int index = 0;
		int length = 0;
		while(sGetProcAddr[index] != '\0'){   // 计算长度
			index ++;
		}
		length = index;
		for (index = 0; index < length; index ++){      // 对比
			if (sGetProcAddr[index] != tmp[index]){
				break;
			}
		}
		if (index == length){   // 找到了
			// puts("found");       // 找到对应在序号表的第i个位置
			break;
		}
		// 下一个条目
		i ++;
	}
	i = pAddressOfNameOrdinals[i];
	//printf("i=%d in AddressOfFunctions = 0x%p \n", i, dwKernel32Base + pAddressOfFunctions[i]);
	PGETPROCADDRESS pGetProcAddress = (PGETPROCADDRESS)(dwKernel32Base + pAddressOfFunctions[i]);
	PLOADLIBRARY pLoadLibrary = (PLOADLIBRARY)pGetProcAddress((HMODULE)dwKernel32Base, sLoadLibraryA);
	//printf("loadlibrary: 0x%p \n", pLoadLibrary);
	HMODULE hUser32DLL = pLoadLibrary(sUser32Dll);
	PMESSAGEBOXA pMessageBoxA = (PMESSAGEBOXA)pGetProcAddress(hUser32DLL, sMessageBoxA);
	char sHeader[] = {'M', 'z', '1', 0};
	char sText[] = {'i', 'n', 'j', 'e', 'c', 't', 'e', 'd', 0};
	pMessageBoxA(0,sText ,sHeader,0);
}

int main(){
	shellcode();

	return 0;
}

标签:逆向,dwKernel32Base,index,pLdrDataEntry,LIST,char,ENTRY,shellcode,模板
From: https://www.cnblogs.com/Mz1-rc/p/18474488

相关文章

  • 秘制小模板
    最小生成树PrimCode#include<iostream>#include<queue>usingnamespacestd;constintkMaxN=1e5+1;intn,m;vector<pair<int,int>>g[kMaxN];structNode{intu,w;Node(inta,intb){u=a,w=b;}friendbo......
  • 【模板】模意义下的乘法逆元 2
    原题链接\(通过小学就知道的小费马定理我们可以得知\)\(inv(a)=a^(mod-2)(modp)\)\(我们将其前后通分然后把分子的和加起来最后通过所有数的乘积的逆元进行计算即可\)\(唯一恶心的点就是卡取消同步流\)\(code:\)点击查看代码#include<bits/stdc++.h>#defineintlong......
  • Zabbix模板数据存储在哪里?
    Zabbix的模板数据存储在数据库的哪一个表里面?以MySQL数据库为例,在数据库zabbix中,其实模板数据存储在hosts这个表里面,而不是存在hosts_templates表里面。很多人一看到templates关键字,容易先入为主的以为这个表会存储模板的相关数据。但是实际上,hosts_templates表用于存储主机和模板......
  • 网站如何修改后台代码?模板网站怎么修改?
    修改网站后台代码通常涉及以下几个步骤,具体操作可能会因网站的技术栈和架构而有所不同。以下是一般流程:1.备份现有代码重要:在进行任何修改之前,务必备份现有的代码和数据库。这可以在出现问题时帮助你快速恢复。2.确定修改需求明确你需要对后台代码进行哪些具体的修改,比如......
  • 网站后台怎么修改模板?
    要修改网站后台的模板,通常需要遵循以下步骤。具体步骤可能会根据您使用的CMS(内容管理系统)或框架有所不同,但大体流程相似:登录后台管理界面:使用您的管理员账号登录到网站的后台管理界面。找到模板管理选项:在后台菜单中查找与“模板”、“主题”或“外观”相关的选项。这......
  • 模板网站可以修改内容吗?网站修改资料页面模板?
    模板网站通常提供了多种方式让用户自定义和修改内容,具体方法取决于所使用的模板平台或工具。以下是几种常见的修改方式:文本编辑:大多数模板网站允许用户直接在页面上编辑文本内容,如标题、段落等。图片更换:用户可以通过上传自己的图片来替换模板中的默认图片。颜色调整:一些高级......
  • switch语句逆向分析
    switch语句逆向分析有序小于3时代码:#include"stdafx.h"voidMySwitch(intx){switch(x){case1:printf("numis1\n");break;case2:printf("numis2\n");......
  • 常见逻辑语句逆向分析
    Ifelse语句逆向分析#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>intmain(intargc,char*argv[]){intsum=0;for(inti=0;i<=argc;i++){sum+=i;}returnsum;汇编代码00401006movdwordptr[ebp-8],0;sum=0......
  • 2024 CSP-J/S2 模板复习计划
    2024CSP-J/S2模板复习计划(Starton2024-10-18)说明原来这个计划是2023CSP-J/S2模板复习,现在被拿来当模板集。Day1我的记录@zhenghanyun的记录任务已完成SPFA(不带负环)已完成Floyd已完成Dijkstra已完成拓扑排序已完成单调栈已......
  • 模板网站如何修改代码?修改织梦网站页面模板?
    修改模板网站的代码通常涉及以下几个步骤:备份原始文件:在开始任何修改之前,确保备份原始文件。这可以帮助您在遇到问题时恢复到初始状态。了解文件结构:浏览模板文件夹,了解其结构。常见的文件夹包括 css、js、img 和 html 文件。查看 README 或其他文档,了解模板的......