逆向工程核心原理 Chapter27 | 代码注入

2024-09-05 16:12

本文主要是介绍逆向工程核心原理 Chapter27 | 代码注入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码注入知识点

在这里插入图片描述

代码注入与DLL注入的区别

代码注入和DLL注入的区别在于:我们必须把参数也注入目标进程。

DLL注入不需要考虑参数地址,只需要考虑LPTHREAD_START_ROUTINE的地址和DLL字符串地址,

是因为参数在DLL里面,目标进程加载DLL后会在内存中加载参数。

而代码注入则不行,如果还是像DLL那样硬编码参数,就会内存访问错误。

具体可以看这个例子:

在这里插入图片描述

采用DLL注入后的代码:

在这里插入图片描述

可以看到参数在DLL中是硬编码的。由于DLL可以重定位,所以不会出现内存访问错误。

但换成代码注入就不行。

DLL注入的LPTHREAD_START_ROUTINE传的是LoadLibrary,lParameter传的是DLL字符串地址。

代码注入的LPTHREAD_START_ROUTINE传的是调用代码的地址,lParameter传的是参数数组的地址。

使用代码注入的原因

在这里插入图片描述

练习示例

这里先逆向看看,后面再手写一遍代码。

代码注入的代码部分:

在这里插入图片描述

设置参数部分:在这里插入图片描述

WriteProcessMemoryCreateRemoteThread部分:

在这里插入图片描述

精妙至极!

代码编写

代码有好几个点要注意:

  • typedef int(WINAPI* PFMessageBoxA)

  • pRemoteBuf[1]那儿分配的是待执行的函数,所以要PAGE_EXECUTE_READWRITE

    pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

  • ThreadProc大小利用的原理是:

    在这里插入图片描述

    这样更简便一点。

不知道为什么一直注入不了,一运行notepad就退出了。。
(就当学思路+熟悉WinAPI吧( )

#include<tchar.h>
#include<Windows.h>
#include<iostream>
#include<stdlib.h>
#include<stdio.h>using namespace std;/*
定义好结构,简化操作
*/
typedef struct _THREAD_PARAMETER {FARPROC pFunc[2]; // Funcchar szBuf[4][128]; // Parameter
}THREAD_PARAM, * PTHREAD_PARAM;// LoadLibraryA
typedef HMODULE(WINAPI* PFLoadLibraryA)(LPCSTR lpLibFileName);// GetProcAddress
typedef FARPROC(WINAPI* PFGetProcAddress)(HMODULE hModule,LPCSTR lpProcName);// MessageBoxA
typedef int(WINAPI* PFMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);DWORD WINAPI ThreadProc(LPVOID lParam) {PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;HMODULE hModule = NULL;FARPROC pFunc = NULL;// LoadLibraryA("user32.dll")hModule = ((PFLoadLibraryA)(pParam->pFunc[0]))(pParam->szBuf[0]);// GetProcAddress("MessageBoxA")pFunc = (FARPROC)((PFGetProcAddress)(pParam->pFunc[1]))(hModule, pParam->szBuf[1]);// MessageBoxA(0,text,caption,MB_OK)((PFMessageBoxA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);return 0;
}BOOL InjectCode(DWORD dwPid) {HMODULE hModule = NULL;THREAD_PARAM param = { 0, };HANDLE hProcess = NULL;HANDLE hThread = NULL;LPVOID pRemoteBuf[2] = { 0, };DWORD dwSize = 0;// 设置参数hModule = GetModuleHandleA("kernel32.dll");param.pFunc[0] = GetProcAddress(hModule, "LoadLibraryA");param.pFunc[1] = GetProcAddress(hModule, "GetProcAddress");strcpy_s(param.szBuf[0], "user32.dll");strcpy_s(param.szBuf[1], "MessageBoxA");strcpy_s(param.szBuf[2], "INJECTED!");strcpy_s(param.szBuf[3], "N0zoM1z0");// OpenProcesshProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);if (hProcess == NULL) {cerr << "Error Finding Process!\nCheck PID\n";return FALSE;}// VirtualAllocEx For ParamdwSize = sizeof(THREAD_PARAM);pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);// WriteProcessMemoryBOOL OK = WriteProcessMemory(hProcess, pRemoteBuf[0], (LPVOID)&param, dwSize, NULL);if (!OK) {cerr << "ERROR WriteProcessMemory!\n";return FALSE;}// VirtualAllocEx For ThreadProcdwSize = (DWORD)InjectCode - (DWORD)ThreadProc;pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);// WriteProcessMemoryOK = WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)ThreadProc, dwSize, NULL);if (!OK) {cerr << "ERROR WriteProcessMemory!\n";return FALSE;}// CreateRemoteThreadhThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL);if (hThread == NULL) {cerr << "ERROR CreateRemoteThread!\n";return FALSE;}WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);CloseHandle(hProcess);cout << "DONE!\n";return TRUE;
}int main(int argc, CHAR* argv[]) {if (argc < 2) {printf("Usage: %s pid\n", argv[0]);return 1;}DWORD dwPid = (DWORD)atol((LPCSTR)argv[1]);cout << "argv[1]: " << argv[1] << "\n";cout << "PID: " << dwPid << "\n";InjectCode(dwPid);return 0;
}

我用作者的源程序也是notepad直接退出(?)

换win7测试一下作者的exe。

好吧,win7可行。。

在这里插入图片描述

然后我自己的在win10的vs上编译,用的vs2022,所以没法兼容win7。。。会报错缺少dll。

高版本Windows和vs的代码注入后面再来看看。

调试

x32dbg设置几个选项就行了,

在这里插入图片描述

这篇关于逆向工程核心原理 Chapter27 | 代码注入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139443

相关文章

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot实现图形验证码的示例代码

《SpringBoot实现图形验证码的示例代码》验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用Hutool提供的小工具实现,本文介绍Sp... 目录项目创建前端代码实现约定前后端交互接口需求分析接口定义Hutool工具实现服务器端代码引入依赖获

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

利用Python在万圣节实现比心弹窗告白代码

《利用Python在万圣节实现比心弹窗告白代码》:本文主要介绍关于利用Python在万圣节实现比心弹窗告白代码的相关资料,每个弹窗会显示一条温馨提示,程序通过参数方程绘制爱心形状,并使用多线程技术... 目录前言效果预览要点1. 爱心曲线方程2. 显示温馨弹窗函数(详细拆解)2.1 函数定义和延迟机制2.2

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro