代码重定位技术

news2024/11/15 17:50:16

1. 什么是重定位

本来每个进程都各自的进程地址空间, 但如果使用了比如注入技术后, 自身的那段代码就会进入到别人的进程地址空间内, 这将导致内部使用的API地址和变量地址发生变化, 因为注入到的位置和自身在自己进程地址空间种的基址很可能会不一样。

2. 如何解决重定位问题

使用汇编语言可以很好的解决重定位问题, 下面来看这段代码:

call $+5   ;机器码实际上是 E8 xx xx xx xx,一共5个字节
           ;$是但当前指令所在的地址,$+5就是越过当前指令
           ;获取下一条指令也就是pop ebx的地址并压入堆栈
pop ebx   ;把pop ebx指令所在的地址[由call压入]弹出到ebx中

还有一段等价代码

call NEXT
NEXT:
pop ebx

上面两端代码的含义是一样的, 都是为了获取当前进程空间种当前指令的动态地址
重定位

3. 实例

下面这个实例使用了远线程注入方式, 把一段重定位过的汇编代码注入到了目标进程

.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include windows.inc
include kernel32.inc
include user32.inc
include Comctl32.inc
include shell32.inc

includelib kernel32.lib
includelib user32.lib
includelib Comctl32.lib
includelib shell32.lib

DlgProc			PROTO	:HWND,:UINT,:WPARAM,:LPARAM

.const

IDD_DIALOG			equ 101
IDC_EDT_BROWSE		equ 1001
IDC_BTN_BROWSE		equ 1002
IDC_BTN_INJECT		equ 1003
IDC_STATIC_STATUS		equ 1004
IDC_EDT_PID			 equ 1005
IDC_STATIC_PID		equ 1006

.data?
hInstance			dd ?

.data 
g_strProcessName db MAX_PATH dup(0)
g_ddShellcodeSize dd offset INJECT_CODE_END - offset INJECT_CODE

g_szUser32 db "user32.dll", 0
g_szMsgBox db "MessageBoxA", 0

g_szOk db "状态: 成功", 0
g_szFail db "状态: 失败", 0
.code

start:
	invoke GetModuleHandle,NULL
	mov	hInstance,eax

    	invoke InitCommonControls
	invoke DialogBoxParam,hInstance,IDD_DIALOG,NULL,addr DlgProc,NULL
	invoke ExitProcess,0

; ofst = new - origin
; NewMsgBox = OldMsgBox + ofst
INJECT_CODE:
	jmp STARTINJ

	g_szMsgData db "你快乐了吗?", 0
	g_szMsgCaption db "哈哈", 0
	g_pfnMessageBoxA dd 0
STARTINJ:
	; 进行重定位, 获取偏移
	call NEXT 
NEXT:
	pop ebx 
	sub ebx, offset NEXT
	
	push MB_OK
	; 对MessageBoxA的标题进行重定位
	mov eax, offset g_szMsgCaption
	add eax, ebx
	push eax
	; 对MessageBoxA的内容进行重定位
	mov eax, offset g_szMsgData
	add eax, ebx
	push eax
	
	push NULL
	; 对MessageBoxA进行重定位
	mov eax, offset g_pfnMessageBoxA
	add eax, ebx
	call dword ptr [eax]
	ret

INJECT_CODE_END:


GetPidByProcessName PROC stdcall hWnd:HWND
	LOCAL @hSnapshot:HANDLE 
	LOCAL @stPe:PROCESSENTRY32 
	LOCAL @dwPid:DWORD

	; 初始化局部变量
	mov @dwPid, 0
	mov @hSnapshot, INVALID_HANDLE_VALUE
	; 获取目标进程名
	invoke GetDlgItemText, hWnd, IDC_EDT_PID, offset g_strProcessName, size g_strProcessName
	; 创建快照句柄
	invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS, 0
	mov @hSnapshot, eax 
	cmp eax, INVALID_HANDLE_VALUE
	je CLEARSTUFF
	; 遍历进程
	mov @stPe.dwSize, size PROCESSENTRY32
	invoke Process32First, @hSnapshot, addr @stPe
	test eax, eax
	jz CLEARSTUFF
GETPIDLOOP:
	invoke lstrcmp, addr @stPe.szExeFile, addr g_strProcessName
	jz GETPIDOKAY
	invoke RtlZeroMemory, addr @stPe, size PROCESSENTRY32
	mov @stPe.dwSize, size PROCESSENTRY32
	invoke Process32Next, @hSnapshot, addr @stPe 
	test eax, eax 
	jnz GETPIDLOOP
	jmp CLEARSTUFF
GETPIDOKAY:
	mov eax, @stPe.th32ProcessID
	mov @dwPid, eax
CLEARSTUFF:
	cmp @hSnapshot, INVALID_HANDLE_VALUE
	jz ENDING
	invoke CloseHandle, @hSnapshot 
	mov @hSnapshot, INVALID_HANDLE_VALUE
ENDING:
	mov eax, @dwPid
	ret

GetPidByProcessName endp

InjectObject PROC stdcall hWin:HWND
	LOCAL @hProcess:HANDLE
	LOCAL @dwPid:DWORD
	LOCAL @pShellcode:PBYTE
	LOCAL @dwWritten:DWORD
	LOCAL @hRemoteThread:DWORD
	LOCAL @dwOldProtect:DWORD
	; 初始化局部变量
	mov @hRemoteThread, 0
	mov @hProcess, NULL
	mov @pShellcode, NULL
	mov @dwWritten, 0
	mov @dwPid, 0
	; 获取MessageBoxA的地址
	invoke VirtualProtect, INJECT_CODE, 64, PAGE_EXECUTE_READWRITE, addr @dwOldProtect
	invoke GetModuleHandle, offset g_szUser32
	invoke GetProcAddress, eax, offset g_szMsgBox
	mov g_pfnMessageBoxA, eax
	invoke VirtualProtect, INJECT_CODE, 64, addr @dwOldProtect, addr @dwOldProtect
	; 获取目标进程PID
	invoke GetDlgItemInt, hWin, IDC_EDT_PID, FALSE, FALSE
	mov @dwPid, eax
	test eax, eax 
	jz ENDFUNC
	; 打开目标进程
	invoke OpenProcess, PROCESS_ALL_ACCESS, FALSE, @dwPid
	mov @hProcess, eax
	test eax, eax 
	jz ENDFUNC
	; 在目标进程内分配空间 
	invoke VirtualAllocEx, @hProcess, NULL, g_ddShellcodeSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
	mov @pShellcode, eax
	test eax, eax
	jz ENDFUNC
	; 把shellcode写入目标进程
	invoke WriteProcessMemory, @hProcess, @pShellcode, INJECT_CODE, g_ddShellcodeSize, addr @dwWritten
	test eax, eax
	jz ENDFUNC
	; 创建远程线程
	invoke CreateRemoteThread, @hProcess, NULL, 0, @pShellcode, NULL, 0, NULL
	mov @hRemoteThread, eax
	test eax, eax
	jz ENDFUNC
	invoke Sleep, 500
ENDFUNC:
	cmp @hRemoteThread, 0
	jz @F
	invoke CloseHandle, @hRemoteThread
	mov @hRemoteThread, 0
@@:
	cmp @hProcess, 0
	jz @F
	invoke CloseHandle, @hProcess
	mov @hProcess, 0
@@:
	ret

InjectObject endp


DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

	mov		eax,uMsg
	.if eax==WM_INITDIALOG
	
	.elseif eax==WM_COMMAND
		mov eax, wParam
		cmp ax, IDC_BTN_BROWSE
		jnz @F
		; 获取目标进程PID
		invoke GetPidByProcessName, hWin 
		invoke SetDlgItemInt, hWin, IDC_EDT_PID, eax, FALSE
		test eax, eax
		jz NOEXEC
		mov eax, TRUE
		ret
@@:
		cmp ax, IDC_BTN_INJECT
		jnz NOEXEC
		invoke InjectObject, hWin
		test eax, eax
		jz NOEXEC
		invoke SetDlgItemText, hWin, IDC_STATIC_STATUS, offset g_szOk
		mov eax, TRUE
		ret
NOEXEC:
		invoke SetDlgItemText, hWin, IDC_STATIC_STATUS, offset g_szFail
		mov eax, FALSE
		ret 
	.elseif eax==WM_CLOSE
		invoke EndDialog,hWin,0
	.else
		mov		eax,FALSE
		ret
	.endif
	mov		eax,TRUE
	ret

DlgProc endp

end start

运行如下:
在这里插入图片描述
(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/797144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cspm是什么?考了有用吗?

CSPM是项目管理专业人员能力评价等级证书,相当于 PMP 的本土化,CSPM 相关问题大家都很关心,今天就给大家全面解答一下 CSPM到底是何方神圣? 文章主要是解答下面几个常见问题,其他问题可以留言或者私信咨询我哦~ 一、什…

在Windows 10和11中恢复已删除的照片

可以在Windows 10或11上恢复已删除的照片吗? 随着技术的发展,越来越多的用户习惯在电子设备上存储照片。如果这些照片被删除,可能会给用户带来重大损失。当照片丢失时,您可能会想是否可以恢复已删除的照片? …

ChatGPT的应用与发展趋势:解析人工智能的新风口

目录 优势 应用领域 发展趋势 总结 在人工智能技术迅猛发展的时代,自然语言处理系统的提升一直是研究者们追求的目标。作为人工智能领域的重要突破之一,ChatGPT以其出色的语言模型和交互能力,在智能对话领域取得了重要的进展。 ChatGPT是…

理解Linux内核是个什么东西

我们不妨想一下进程在什么时候才能感知到内核的存在。在malloc分配内存的时候,最终会调用内核的sys_mmap系统调用来申请虚拟内存空间;在fork创建子进程的时候,最终会调用内核的sys_fork来复制父进程;在open打开文件的时候&#xf…

【Java编程案例】面向对象实现模拟物流快递系统

文章目录 一、案例目标二、案例分析1. 交通工具类2. 保养接口3. 专用运输车类4. 定位功能接口5. 快递类 三、测试类四、总结 在现代社会,网购已经成为人们生活的重要组成部分。当用户在购物网站中下订单后,订单中的货物经过一系列的流程,最终…

使用LORA组网利用MQTT协议上报温湿度,到MQTT服务器的项目组成和编程的几点建议

使用LoRa组网利用MQTT协议上报温湿度数据到MQTT服务器的项目组成和编程建议如下: 硬件组成: 温湿度传感器:用于测量环境温度和湿度数据。 LoRa模块:用于无线通信,将温湿度数据通过LoRa协议发送到网关。 LoRa网关&am…

Nacos配置中心的使用

Nacos配置中心的使用 上一节直通车 Nacos注册中心的使用 由于注册中心、配置中心已经被Nacos中间件接管了,所以在代码中只需要给生产者、消费者添加配置即可,不需要像Eureka一样另外起服务了。 Github文档 https://github.com/spring-cloud-incubat…

【java】【面对对象高级3】多态 + final + 抽象类 + 接口

目录 1、多态 1.1 认识多态 1.1.1 对象多态 1.1.2 行为多态 1.1.3 成员变量不谈多态 1.2 使用多态的好处 1.3 多态下的类型转换问题 2、final 2.1 认识final 2.1.1 修饰类 2.1.2 修饰方法 2.1.3 修饰变量 2.2 补充知识:常量详解 3、抽象类abstract 3.1 …

Linux 下的基本指令

pwd pwd 显示当前你所在的路径 ls ls 查看当前路径目录下的所有文件 ls-l ls-l 显示当前目录下的所有文件,包括文件的详细信息:大小,格式,日期等 mkdir mkdir name 创建一个名为name的文件夹, cd cd name 进…

如何在Mac上玩3A?我来教你最简单的方法

如何在mac上玩3A?我来教你最简单的方法 最近苹果在新的发布会上公布了Mac的新系统:macos sonoma,同时也发布了Game Porting Toolkit这一款游戏转译软件,作为果粉当然很激动,当然该款软件还在测试中,一般用…

【OpenGL学习】之着色器GLSL基础

基本类型: 类型说明void空类型,即不返回任何值bool布尔类型 true,falseint带符号的整数 signed integerfloat带符号的浮点数 floating scalarvec2, vec3, vec4n维浮点数向量 n-component floating point vectorbvec2, bvec3, bvec4n维布尔向量 Boolean vectorivec2, ivec3, iv…

物联网的通信协议

物联网的通信协议 目录 物联网的通信协议一、UART串口通信1.1 串口通信1.2 异步收发1.3 波特率1.4 串口通信协议的数据帧1.5 优缺点1.5.1 优点1.5.2 缺点 二、I^2^C2.1 I^2^C2.2 I^2^C2.3 数据有效性2.4 起始条件S和停止条件P2.5 数据格式2.6 协议数据单元PDU2.7 优缺点2.7.1 优…

mybatis_分页

目的&#xff1a; 减少数据处理量&#xff0c;提高效率 普通sql&#xff1a; 语法&#xff1a;select * from user limit startIndex,pageSize; SELECT * from user limit 3; #[0,n] mybatis_sql: 接口&#xff1a; //分页查询List<User> getUserByLimit(Map<…

【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块16

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

四、约束-3.外键约束

一、概念 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性。 【例】 准备数据 -- 准备数据 create table dept(id int auto_increment comment ID primary key ,name varchar(50) not null comment 部门名称 ) comment 部门表; insert into de…

STM32CubeMX配置STM32G031多通道ADC + DMA采集(HAL库开发)

时钟配置HSI主频配置64M 勾选打开8个通道的ADC 使能连续转换模式 添加DMA DMA模式选择循环模式 使能DMA连续请求 采样时间配置160.5 转换次数为8 配置好8次转换的顺序 配置好串口&#xff0c;选择异步模式配置好需要的开发环境并获取代码 修改main.c 串口重定向 #include &…

【第一阶段】Kotlin的空检查

空检查 代码&#xff1a; fun main() {var info:stringprintln(info) }在Java中可以直接不给默认值&#xff0c;但是在kotlin中必须给默认值不然就会报错 正确写法应该为&#xff1a; fun main() {var info:String" "println("info$info") }执行结果&…

【基于Spark的电影推荐系统】环境准备

概览 本科毕设做过电影推荐系统&#xff0c;但当时的推荐算法只有一个&#xff0c;现在已经忘记大部分了&#xff0c;当时也没有记录&#xff0c;因此写这个博客重新来记录一下。此外&#xff0c;技术栈由于快秋招原因来不及做过多的部分&#xff0c;因此只实现简单的功能&…

uniapp跨平台项目实战失物招领

失物招领项目虽然是一个小项目&#xff0c;但是内部的功能还是很全的&#xff0c;比如发布消息&#xff0c;包含图片或者是视频&#xff0c;获取数据&#xff0c;包含分页的数据获取&#xff0c;同时该项目也包含了多表关联的业务设计。 学习本项目能获得的经验有&#xff0c;数…

Selenium的学习

介绍下学习selenium的经验。之前有网友要求我给布置作业&#xff0c;那么我整理一下就全部列在这里。每一步给出一个小题目。 selenium是一个比较古老也比较流行的自动化测试库。他的特点是&#xff0c;版本较多&#xff0c;以至于在网上搜到很多教程都是过时的。 一、Seleniu…