地址无关代码

这篇具有很好参考价值的文章主要介绍了地址无关代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

水不脏人,人却脏水。这就是上善若水?

前言

我们时常说地址无关和地址相关代码是什么?

假设我们有一段代码,这段代码可以随意粘贴到任何程序中运行那么我可以简单的理解为这就是位置无关代码。

我们看下如下的代码:

#include<Windows.h>
int main()
{
	return MessageBoxA(NULL,"hello","world",MB_OK);
}

这段代码对应的汇编代码如下:
地址无关代码
下划线就是被重定位后的地址。
地址无关代码
如果我们把这段汇编代码赋值到其他进程是无法运行的。
我们简单举例来说
本例中的push 00E2100是压入world字符串所在地址,但是其他进程00E2100指代的是什么是无法知晓。

地址无关代码

所以我们怎么才能写一个地址无关代码?

地址无关代码编写

案例仅参考在windows ,linux同理

  1. 将字符串改为字符数组
  2. 关闭安全检查
  3. 修改入口点
  4. 关闭编译器优化
  5. 库函数调用方式修正

将字符串改为字符数组

看一下以下代码


#include<Windows.h>

int main()
{
	char szText[] = { 'h', 'h',' e',' l',' l',' o','\0' };
	char szText2[] = "world";
	 MessageBoxA(NULL, szText, szText2,MB_OK);
	 return EXIT_SUCCESS;
}

地址无关代码
你会发现如果我们字符串的会引用数据地址,而字符数组会在自己用assic直接构造。

关闭安全检查

也许你留意到以下代码
地址无关代码
上面代码是用来检查堆栈溢出等。
你可以关闭整个检查如下图所示:
地址无关代码

修改入口点

我们main其实在运行前需要准备好c库运行环境,所以我们首先会运行一个叫mainCRTStartup函数,
函数源码地址参考:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\crt\src\vcruntime

//exe_main.cpp
//
// exe_main.cpp
//
//      Copyright (c) Microsoft Corporation. All rights reserved.
//
// The mainCRTStartup() entry point, linked into client executables that
// uses main().
//
#define _SCRT_STARTUP_MAIN
#include "exe_common.inl"


extern "C" DWORD mainCRTStartup(LPVOID)
{
    return __scrt_common_main();
}

我们可以修改我们的函数为入口点
地址无关代码

关闭编译器优化

我们前面说过说过字符数组会避免地址引用,但是对于过长字符数组就会转化为多媒体指令的调用了

#include<Windows.h>

int main()
{

	char szText[] = { 'h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h','h', 'h',' e',' l',' l',' o','\0' };
	char szText2[] = "world";


	 MessageBoxA(NULL, szText, szText2,MB_OK);

	 return EXIT_SUCCESS;
}

如下图的 xmm
地址无关代码

地址无关代码

库函数调用方式修正

Window函数调用中会存在一个IAT机制,如下图会进行间接跳转
地址无关代码
很显然这段跳转绑定在正运行程序IAT,因此我们往往需要很特殊的方式去调用。

我们可以如此这般解决:

  1. 通过PEB获取kernel32.dll地址
  2. 自行编写一个GetProcAddress 获取 kernel32.dll中的GetProcAddress LoadLibraryA函数
  3. 得到这个两个函数后就可以自行加载某个系统库然后获取对应函数了
// ShellCodeStudy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<Windows.h>


typedef FARPROC(WINAPI * PFN_GetProcAddress)(
	_In_ HMODULE hModule,
	_In_ LPCSTR lpProcName
);


typedef
HMODULE
(WINAPI
*PNF_LoadLibraryA)(
	_In_ LPCSTR lpLibFileName
);

typedef int(WINAPI *PNF_MessageBoxA)(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCSTR lpText,
	_In_opt_ LPCSTR lpCaption,
	_In_ UINT uType);


//获取keenel32模块 https://xz.aliyun.com/t/10478
HMODULE GetKernelBase() {


	HMODULE hMod = nullptr;
	__asm {
		mov  eax, dword ptr fs : [0x30]
		mov  eax, dword ptr [eax + 0x0C]
		mov  eax, dword ptr  [eax + 0x0C]
		mov  eax, dword ptr [eax]
		mov  eax, dword ptr  [eax]
		mov  eax, dword ptr  [eax + 0x18]
		mov hMod, eax
	}
	return hMod;
}

void* MyGetProcAddress(HMODULE hMod, LPCSTR lpFunName)
{
	IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;
	IMAGE_NT_HEADERS32* pNtHeader = (IMAGE_NT_HEADERS32*)((DWORD)hMod + pDosHeader->e_lfanew);
	IMAGE_DATA_DIRECTORY* pExportDirectoty = &pNtHeader->OptionalHeader.DataDirectory[0];
	IMAGE_EXPORT_DIRECTORY* pExport = (IMAGE_EXPORT_DIRECTORY*)((DWORD)hMod + pExportDirectoty->VirtualAddress);
	if ((DWORD)lpFunName > 0xffff)
	{
		//名称查找
		for (size_t i = 0; i < pExport->NumberOfNames; i++)
		{
			char* pName = (char*)(*(DWORD*)((DWORD)hMod + pExport->AddressOfNames + i * sizeof DWORD)+ (DWORD)hMod);
			if (strcmp(lpFunName, pName) == 0)
			{
				DWORD  dwOrdinals = *(WORD*)((DWORD)hMod + pExport->AddressOfNameOrdinals+ i * sizeof WORD);
				return (void*)(*(DWORD*)((DWORD)hMod+pExport->AddressOfFunctions+ dwOrdinals* sizeof DWORD)+(DWORD)hMod);
			}
		}
	}
	else {  
		DWORD  dwOrdinals = (DWORD)lpFunName - pExport->Base;
		if (dwOrdinals>=pExport->NumberOfFunctions)
		{
			return 0;
		}
		return (void*)(*(DWORD*)((DWORD)hMod + pExport->AddressOfFunctions + dwOrdinals * sizeof DWORD) + (DWORD)hMod);

	}
}

int Entry()
{

	char szText[] = { 'h',' e',' l',' l',' o','\0' };
	char szText2[] = "sdas";
	char szTitle[] = { 'w',' o',' r',' l',' d','\0' };

	char szGetProcAddress[] = { 'G','e','t','P','r','o','c','A', 'd','d','r','e','s','s','\0'};
					
	char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r', 'a','r','y','A','\0' };

	char szUser32[] = {'u','s','e','r','3','2','\0' };

	char szMessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A','\0'};


	HMODULE hKernnel32 = GetKernelBase();
	
	PFN_GetProcAddress pfnGetProcAddress =(PFN_GetProcAddress)MyGetProcAddress(hKernnel32, szGetProcAddress);

	PNF_LoadLibraryA pfnLoadLibraryA = (PNF_LoadLibraryA)pfnGetProcAddress(hKernnel32, szLoadLibraryA);

	HMODULE hUser32 = pfnLoadLibraryA(szUser32);


	PNF_MessageBoxA pnfMessageBoxA = (PNF_MessageBoxA)pfnGetProcAddress(hUser32,szMessageBoxA);
	

	return  pnfMessageBoxA(NULL, szText, szTitle, MB_OK);

}

地址无关代码文章来源地址https://www.toymoban.com/news/detail-449759.html

到了这里,关于地址无关代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【线性代数】两个向量组等价,其中一个向量组线性无关,另一个向量组也是线性无关吗?

    两个向量组等价,其中一个向量组线性无关,另一个向量组也是线性无关吗? 不一定,当两个向量组中的向量个数也相同时,结论才成立.若向量个数不相同,结论不成立. 例如: 向量组一:(1,0),(0,1) 向量组二:(1,0),(0,1),(1,1) 两个向量组等价,向量组一线性无关,向量组二线性相关 参考

    2024年02月02日
    浏览(52)
  • 矩阵线性无关的证明

    假设在维实数空间中有四个矩阵:,,,,证明这四个矩阵是线性无关的。 在一个线性空间中,若一组矩阵是线性无关的则可以作为该空间的一组基,这意味着该空间内的所有矩阵都可以由改组基唯一表示出来,我们假设 ,这意味着,这与向量的线性无关具有类似性,为此

    2024年02月13日
    浏览(28)
  • Sample语言上下文无关文法

    表达式 : 表达式-算术表达式|关系表达式|布尔表达式|赋值表达式 算术表达式 算术表达式 - 算术表达式 + 项 | 算术表达式 - 项|项 项 - 项* 因子|项/因子|项%因子因子 因子 - (算术表达式)常量|变量|函数调用 常量 - 数值型常量字符型常量 变量 - 标识符 函数调用 - 标识符(实参列

    2023年04月26日
    浏览(39)
  • 【Linux权限管理】文件:毁灭我与我无关

    一台Linux机器的用户分为两类: 超级用户和普通用户 。 注意我这里说的用户的并不是一个固定的人,例如你本身就有root账号,但你也可以使用自己创建普通账号。当你使用root账号时,你就是一个超级用户,当你使用普通账号时,你就是一个普通用户。更简单地说,这里的用

    2024年02月09日
    浏览(52)
  • 【证明】矩阵不同特征值对应的特征向量线性无关

    定理 1 设 λ 1 , λ 2 , ⋯   , λ m lambda_1,lambda_2,cdots,lambda_m λ 1 ​ , λ 2 ​ , ⋯ , λ m ​ 是方阵 A boldsymbol{A} A 的 m m m 个特征值, p 1 , p 2 , ⋯   , p m boldsymbol{p}_1,boldsymbol{p}_2,cdots,boldsymbol{p}_m p 1 ​ , p 2 ​ , ⋯ , p m ​ 依次是与之对应的特征向量,如果 λ 1 , λ 2 , ⋯   , λ

    2024年02月09日
    浏览(46)
  • [C#]WPF 分辨率的无关性的问题

    首先得解什么是Dpi(Density independent pixels ,设备无关像素),百度百科的解释DPI是指每英寸的像素,对应界面显示即是屏幕上每英寸的像素。 如标准的Windows DPI(96Dpi),代表1英寸96个像素。 假设有一个96px*96px的按钮,如果在标准标准的Windows DPI的情况下看起来就是英寸的大小

    2024年02月15日
    浏览(44)
  • 在vscode中使用git时如何忽略无关文件的变更

    在源代码管理中直接右键不想上传的变更,选择添加到.gitignore中 右键添加到.gitignore 以上操作后会在根目录下生成一个.gitignore文件,可直接编辑来达到忽略无关文件变更的效果 在.gitignore中直接修改,不同步一类文件,格式为*.x(后缀为你不想上传的文件后缀) 此时已屏蔽的文

    2024年01月18日
    浏览(37)
  • 线性代数|证明:矩阵不同特征值对应的特征向量线性无关

    定理 1 设 λ 1 , λ 2 , ⋯   , λ m lambda_1,lambda_2,cdots,lambda_m λ 1 ​ , λ 2 ​ , ⋯ , λ m ​ 是方阵 A boldsymbol{A} A 的 m m m 个特征值, p 1 , p 2 , ⋯   , p m boldsymbol{p}_1,boldsymbol{p}_2,cdots,boldsymbol{p}_m p 1 ​ , p 2 ​ , ⋯ , p m ​ 依次是与之对应的特征向量,如果 λ 1 , λ 2 , ⋯   , λ

    2024年02月07日
    浏览(61)
  • 如何把一个 Git 仓库的分支加入另一个无关的 Git 仓库

      笔者需要将两个无关的 Git 仓库合并,也就是把一个 Git 仓库的分支加入另一个无关的 Git 仓库。笔者琢磨了一下之后就实现了。方法如下。 笔者的运行环境: git version 2.37.0.windows.1 TortoiseGit 2.11.0.0 IntelliJ IDEA 2023.1.1 (Ultimate Edition) Windows 10 教育版 为了便于说明,作如下约定

    2024年02月12日
    浏览(59)
  • 11.5序列检测、含无关项~,不重叠~,报错,always模板与经验复盘

    a是一位的信号,检测连续的一串信号 遍历法 从第一位往后不断和目标串比较 不用管是不是阻塞非阻塞的含义了,难以理解,用了一定不会出问题,不用可能出问题,分析不出来 还是和之前一样,保留一串,不过检测的时候分为两部分,两部分检测都通过了就表示匹配成功

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包