水不脏人,人却脏水。这就是上善若水?
前言我们时常说地址无关和地址相关代码是什么?
假设我们有一段代码,这段代码可以随意粘贴到任何程序中运行那么我可以简单的理解为这就是位置无关代码。
我们看下如下的代码:
#include
int main()
{
return MessageBoxA(NULL,"hello","world",MB_OK);
}
这段代码对应的汇编代码如下:
下划线就是被重定位后的地址。
如果我们把这段汇编代码赋值到其他进程是无法运行的。
我们简单举例来说
本例中的push 00E2100
是压入world字符串所在地址,但是其他进程00E2100
指代的是什么是无法知晓。
所以我们怎么才能写一个地址无关代码?
地址无关代码编写案例仅参考在windows ,linux同理
- 将字符串改为字符数组
- 关闭安全检查
- 修改入口点
- 关闭编译器优化
- 库函数调用方式修正
看一下以下代码
#include
int main()
{
char szText[] = { 'h', 'h',' e',' l',' l',' o','}' ;char
[ szText2]= "world" ;MessageBoxA
(NULL,, szText, szText2)MB_OK;return
; EXIT_SUCCESS}
mainCRTStartup
你会发现如果我们字符串的会引用数据地址,而字符数组会在自己用assic直接构造。
也许你留意到以下代码
上面代码是用来检查堆栈溢出等。
你可以关闭整个检查如下图所示:
我们main其实在运行前需要准备好c库运行环境,所以我们首先会运行一个叫C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.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" mainCRTStartup DWORD ()LPVOIDreturn
{
__scrt_common_main ();}
#
我们可以修改我们的函数为入口点
我们前面说过说过字符数组会避免地址引用,但是对于过长字符数组就会转化为多媒体指令的调用了
includeint
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','}'; char[
] szText2="world" ; MessageBoxA(
NULL,,, szText) szText2;MB_OKreturn;
} EXIT_SUCCESSWindow
通过PEB获取kernel32.dll地址
如下图的 xmm
在kernel32.dll
函数调用中会存在一个IAT机制,如下图会进行间接跳转
很显然这段跳转绑定在正运行程序IAT,因此我们往往需要很特殊的方式去调用。
我们可以如此这般解决:
- 自行编写一个GetProcAddress 获取
LoadLibraryA
中的 - 得到这个两个函数后就可以自行加载某个系统库然后获取对应函数了 与// ShellCodeStudy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。函数//
GetProcAddress
#
include
#include
typedefFARPROC
( *)WINAPI ( PFN_GetProcAddress,)
_In_ HMODULE hModule;
_In_ LPCSTR lpProcName
typedefHMODULE
(
*
)WINAPI
(PNF_LoadLibraryA);
_In_ LPCSTR lpLibFileName
typedefint
( *)WINAPI (PNF_MessageBoxA,,
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText)
_In_opt_ LPCSTR lpCaption;
_In_ UINT uType//获取keenel32模块 https://xz.aliyun.com/t/10478GetKernelBase
(
HMODULE )=nullptr {
HMODULE hMod ; ,:
__asm {
mov eax[ dword ptr fs 0x30 ],[
mov eax+ dword ptr 0x0Ceax ] ,[
mov eax+ dword ptr 0x0Ceax ] ,[
mov eax] dword ptr ,eax[
mov eax] dword ptr ,eax[
mov eax+ dword ptr 0x18eax ] ,}
mov hModreturn eax
;
} hModvoid
*
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->OptionalHeader0DataDirectory];*=
IMAGE_EXPORT_DIRECTORY( pExport * )IMAGE_EXPORT_DIRECTORY(()+DWORD)hMod ; pExportDirectoty->VirtualAddressif(
( )0xffffDWORD)lpFunName > //名称查找for
{
(
= 0size_t i ; <; i ++ pExport->NumberOfNames) ichar*
{
=( pName char *)(*(*)DWORD(()+DWORD+hMod * pExport->AddressOfNames sizeof i ) + DWORD() )DWORD;hModif(
strcmp (,)lpFunName== pName0 ) =*
{
DWORD dwOrdinals ( *)WORD(()+DWORD+hMod * pExport->AddressOfNameOrdinalssizeof i ) ; WORDreturn(
void *)(*(*)DWORD(()+DWORD+hMod*pExport->AddressOfFunctionssizeof dwOrdinals) + DWORD())DWORD;hMod}}
}
else
=
( {
DWORD dwOrdinals ) -DWORD;lpFunName if pExport->Base(
) returndwOrdinals>=pExport->NumberOfFunctions0
{
; }return
(
void *)(*(*)DWORD(()+DWORD+hMod * pExport->AddressOfFunctions sizeof dwOrdinals ) + DWORD( ) )DWORD;hMod}}
int
Entry
( )char[
{
] szText='h' , { ' e',' l',' l',' o','}';char []
= szText2"sdas"; char []
= szTitle'w', ' o' { ,' r',' l',' d','}';char[ ]=
'G' szGetProcAddress,'e' , { 't','P','r','o','c','A','d','d', 'r','e','s','s','}';char[]='L'
, szLoadLibraryA'o', 'a' { ,'d','L','i','b','r','a','r','y' ,'A','}';char[]= 'u',
's' szUser32,'e' , {'r','3','2','}';char[]='M' ,'e'
, szMessageBoxA's', 's' { ,'a','g','e','B','o','x','A','}';=GetKernelBase();=()
HMODULE hKernnel32 MyGetProcAddress (,);
PFN_GetProcAddress pfnGetProcAddress =(PFN_GetProcAddress)pfnGetProcAddress(hKernnel32, szGetProcAddress);
PNF_LoadLibraryA pfnLoadLibraryA = pfnLoadLibraryAPNF_LoadLibraryA();hKernnel32= szLoadLibraryA()
HMODULE hUser32 pfnGetProcAddress (,szUser32);
PNF_MessageBoxA pnfMessageBoxA return pnfMessageBoxAPNF_MessageBoxA(NULL,hUser32,szMessageBoxA,)
; } szText szTitle MB_OK
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)