编译环境是 VS2013+WDK8.1
测试环境 XP32
就上次发的创建内核线程读写DXF内存,这里就继续完善下,原帖:
http://bbs.pediy.com/showthread.php?t=212347
毕竟创建线程,还要等待线程执行,速度慢了很多吧,感觉别扭
通宵一晚上,查了下资料,把伪装进程弄了出来
测试还是有点效果,不过也不是很完美
必须要过掉 ZwOpenProcess ,NtReadProcessMemory,NtWriteProcessMemory这三个函数HOOK才能读写
不过总算摆脱了线程的方式,而且那三个HOOK也容易过,内心感觉爽了一下.
伪装进程的代码基本上也是下面这帖子抄的,自己简单的修改了下:
http://bbs.pediy.com/showthread.php?t=96427
老样子,对内核不是太了解的我,不会WinDbg,不会双机调试
写出这些代码,基本上都是蓝屏重启千万次慢慢修改的
得出结论,学内核,windbg还是要学的,毕竟没法调试,很多东西都不好弄明白是什么原因,ring3下至少还有OD调试
源码就不打包了,就那么几行代码而已.
先贴代码,再说说遇到不解的问题
VOID ChangeName2(ULONG pProcess1/**被伪装的进程**/, ULONG pProcess2/**要伪装的进程**/)
{
KAPC_STATE kapc1, kapc2;
PUNICODE_STRING CurrentDirectory=NULL,
DllPath=NULL,
ImagePathName=NULL,
CommandLine=NULL,
ldr1_FullName=NULL,
ldr1_BaseName=NULL,
ldr2_FullName=NULL;
ULONG ProcessParameters, peb, ldr, ldr1, ldr2, ldr3,x1;
WCHAR CurrentDirectory2[256] = { 0 },
DllPath2[256] = { 0 },
ImagePathName2[256] = { 0 },
CommandLine2[512] = { 0 },
ldr1_FullName2[256] = { 0 },
ldr1_BaseName2[256] = { 0 },
ldr2_FullName2[256] = { 0 };
peb = *(PULONG)(pProcess1 + 0x1b0);
// DbgPrint("peb = %08X", peb);
KeStackAttachProcess((PEPROCESS)pProcess1, &kapc1);
_try
{
ProcessParameters = *(PULONG)(peb + 0x010);
// DbgPrint("ProcessParameters = %08X", ProcessParameters);
CurrentDirectory = (PUNICODE_STRING)(ProcessParameters + 0x24); //CurrentDirectory
DllPath = (PUNICODE_STRING)(ProcessParameters + 0x30); //DllPath
ImagePathName = (PUNICODE_STRING)(ProcessParameters + 0x38); //ImagePathName
CommandLine = (PUNICODE_STRING)(ProcessParameters + 0x40); //CommandLine
RtlCopyMemory(CurrentDirectory2, CurrentDirectory->Buffer, wcslen(CurrentDirectory->Buffer)*2);
RtlCopyMemory(DllPath2, DllPath->Buffer, wcslen(DllPath->Buffer)*2);
RtlCopyMemory(ImagePathName2, ImagePathName->Buffer, wcslen(ImagePathName->Buffer)*2);
RtlCopyMemory(CommandLine2, CommandLine->Buffer, wcslen(CommandLine->Buffer)*2);
//DbgPrint("CurrentDirectory2 %S %d %S %d", CurrentDirectory2, wcslen(CurrentDirectory2), CurrentDirectory->Buffer, wcslen(CurrentDirectory->Buffer));
//DbgPrint("DllPath %S %d %S %d", DllPath2, wcslen(DllPath2), DllPath->Buffer, wcslen(DllPath->Buffer));
//DbgPrint("ImagePathName %S %d %S %d", ImagePathName2, wcslen(ImagePathName2), ImagePathName->Buffer, wcslen(ImagePathName->Buffer));
//DbgPrint("CommandLine2 %S %d", CommandLine2, wcslen(CommandLine2));
//DbgPrint("CommandLine %S %d", CommandLine->Buffer, wcslen(CommandLine->Buffer));
ldr = *(PULONG)(peb + 0x00C);
ldr1 = *(PULONG)(ldr + 0x00C);
ldr2 = *(PULONG)(ldr + 0x014);
// ldr3 = *(PULONG)(ldr + 0x01C);
ldr1_FullName = (PUNICODE_STRING)(ldr1 + 0x24); //FullDllName 完整路径
ldr1_BaseName = (PUNICODE_STRING)(ldr1 + 0x2C); //BaseDllName 文件名称
ldr2_FullName = (PUNICODE_STRING)(ldr2 + 0x24); //FullDllName 完整路径
RtlCopyMemory(ldr1_FullName2, ldr1_FullName->Buffer, wcslen(ldr1_FullName->Buffer) * 2);//FullName这里写过遍历,好像第一个都是EXE
RtlCopyMemory(ldr1_BaseName2, ldr1_BaseName->Buffer, wcslen(ldr1_BaseName->Buffer) * 2); //BaseName
RtlCopyMemory(ldr2_FullName2, ldr2_FullName->Buffer, wcslen(ldr2_FullName->Buffer) * 2);//FullName这里跟上面一样,ldr2的baseName遍历出来没数据,就不获取修改了
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("KeStackAttachProcess失败1");
}
KeUnstackDetachProcess(&kapc1);
peb = *(PULONG)(pProcess2 + 0x1b0);
KeStackAttachProcess((PEPROCESS)pProcess2, &kapc2);
_try
{
ProcessParameters = *(PULONG)(peb + 0x010);
// RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x24), CurrentDirectory2, wcslen(CurrentDirectory2) * 2);// 这里也不能修改,改了程序会出错...
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x30), DllPath2, wcslen(DllPath2) * 2);
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x38), ImagePathName2, wcslen(ImagePathName2) * 2);
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x40), CommandLine2, wcslen(CommandLine2) * 2);
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x70), L"",0);//WindowTitle
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x78), L"", 0);//DesktopInfo
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x80), L"",0);//ShellInfo
// RtlInitEmptyUnicodeString((PUNICODE_STRING)(ProcessParameters + 0x88), NULL, 0);//RuntimeData 这里遍历是NULL,所以不改
ldr = *(PULONG)(peb + 0x00C);
ldr1 = *(PULONG)(ldr + 0x00C);
ldr2 = *(PULONG)(ldr + 0x014);
// ldr3 = *(PULONG)(ldr + 0x01C); //这里没遍历到进程名称,所以不改了
// RtlInitEmptyUnicodeString((PUNICODE_STRING)(ldr1 + 0x24), ldr1_FullName2, wcslen(ldr1_FullName2) * 2); //FullDllName 完整路径 不知道为什么,改了这里,激活窗口,程序就会消失
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ldr1 + 0x2C), ldr1_BaseName2, wcslen(ldr1_BaseName2) * 2); //BaseName 文件名称
RtlInitEmptyUnicodeString((PUNICODE_STRING)(ldr2 + 0x24), ldr2_FullName2, wcslen(ldr2_FullName2) * 2); //FullDllName 完整路径,ldr2的 baseName没有数据,所以只改 FullName
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("KeStackAttachProcess失败2");
}
KeUnstackDetachProcess(&kapc2);
PUNICODE_STRING str1,str2;
//如果要过DXF读写,修改0x174跟0x1F4 这两处就可以了,其他不用改,至于改这么多,纯当学习了
RtlCopyMemory((PCHAR)(pProcess2 + 0x174), (PCHAR)(pProcess1 + 0x174),16);
str1 = (PUNICODE_STRING)(*(PULONG)(pProcess1 + 0x1F4));
str2 = (PUNICODE_STRING)(*(PULONG)(pProcess2 + 0x1F4));
RtlInitEmptyUnicodeString(str2, str1->Buffer, wcslen(str1->Buffer) * 2);
//EPROCESS->SectionObject->Segment->ControlArea->FileObject->FileName
x1 = *(PULONG)(pProcess1 + 0x138);
if (x1!=0)
{
x1 = *(PULONG)(x1 + 0x14);
x1 = *(PULONG)x1;
x1 = *(PULONG)(x1 + 0x024);
str1 = (PUNICODE_STRING)(x1 + 0x030);
x1 = *(PULONG)(pProcess2 + 0x138);
if (x1!=0)
{
x1 = *(PULONG)(x1 + 0x14);
x1 = *(PULONG)x1;
x1 = *(PULONG)(x1 + 0x024);
str2 = (PUNICODE_STRING)(x1 + 0x030);
RtlInitEmptyUnicodeString(str2, str1->Buffer, wcslen(str1->Buffer) * 2);
}
}
//x1 = *(int*)(pProcess + 0x11C); // VAD 这里不知道怎么遍历 ,就不修改了
//x1 = *(int*)(x1 + 0x10);
//x1 = *(int*)(x1 + 0x018);
//x1 = *(int*)(x1 + 0x024);
//str1 = (PUNICODE_STRING)(x1 + 0x030);
//if (str1)
// DbgPrint("FileName = %S ", str1->Buffer);
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)