前几天在本站看到一篇《api hook实战》的文章,把里面的例子测试了一下,发现只能截获本例子进程的,如何能够实现系统当前所有进程都生效的API HOOK?
如果有相关例子更好!
非常感谢!
如果有相关例子更好!
非常感谢!
解决方案 »
- MFC 小问题
- MFC 开发家庭财务管理信息系统
- 请问:各位大牛,如何用http传送流媒体文件?
- 怎样实现在网页上点击一个文件的下载连接后,就打开自己编写的下载工具执行,并且将下载连接输入带程序的编辑框中?
- 为什么这样写就是编译通不过啊???
- 请问WPARAM LPARAM是什么东西来的
- 求助VC、BCB和图象采集高手
- 关于waitsingleobject和惊群的疑问
- 怎么样在ListCtrl里面往标头和项目里加并显示图片?其中的位图操作是怎样的?
- 我想学习VC++,但没有头绪。不知道该怎么学起……
- 有啥简单的方法可以一次禁止对话框上的所有控件吗?
- 如何使CPropertySheet具有热跟踪功能?
http://www.csdn.net/expert/topic/1079/1079128.xml?temp=.9226343
http://codeguru.earthweb.com/dll/Hijack.html
为什么必须有一个Dll才行呢? 我曾试图将Dll和测试程序中的诸函数写到同一个程序中, 发现只是在这一个程序中HookApi起作用, 其它的MessageBox照旧, 这是什么原因呢? 难道User32.dll在内存中不仅有一个实例? 我查看内存发现在我的程序中MessageBoxA的入口处被修改了, 而在别的程序中仍是原来的, 这让我不明所以.
请各位不吝键盘, up有分.
这么多高手在这里,哎,小弟愿意向各位高手学习
Api拦截并不是一个新的技术,很多商业软件都采用这种技术。对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richter 的修改exe文件的模块输入节,种方法,很安全,但很复杂,而且有些exe文件,没有Dll的输入符号的列表,有可能出现拦截不到的情况。第二种方法就是常用的JMP XXX的方法,虽然很古老,却很简单实用。
本文一介绍第二种方法在Win2k下的使用。第二种方法,Win98/me 下因为进入Ring0级的方法很多,有LDT,IDT,Vxd等方法,很容易在内存中动态修改代码,但在Win2k下,这些方法都不能用,写WDM太过复杂,表面上看来很难实现,
其实不然。Win2k为我们提供了一个强大的内存Api操作函数---VirtualProtectEx,WriteProcessMemeory,ReadProcessMemeory,有了它们我们就能在内存中动态修改代码了,其原型为:
BOOL VirtualProtectEx(
HANDLE hProcess, // 要修改内存的进程句柄
LPVOID lpAddress, // 要修改内存的起始地址
DWORD dwSize, // 修改内存的字节
DWORD flNewProtect, // 修改后的内存属性
PDWORD lpflOldProtect // 修改前的内存属性的地址
);
BOOL WriteProcessMemory(
HANDLE hProcess, // 要写进程的句柄
LPVOID lpBaseAddress, // 写内存的起始地址
LPVOID lpBuffer, // 写入数据的地址
DWORD nSize, // 要写的字节数
LPDWORD lpNumberOfBytesWritten // 实际写入的子节数
);
BOOL ReadProcessMemory(
HANDLE hProcess, // 要读进程的句柄
LPCVOID lpBaseAddress, // 读内存的起始地址
LPVOID lpBuffer, // 读入数据的地址
DWORD nSize, // 要读入的字节数
LPDWORD lpNumberOfBytesRead // 实际读入的子节数
);
具体的参数请参看MSDN帮助。在Win2k下因为Dll和所属进程在同一地址空间,这点又和Win9x/me存在所有进程存在共享的地址空间不同,
因此,必须通过钩子函数和远程注入进程的方法,现以一个简单采用钩子函数对MessageBoxA进行拦截例子来说明:
其中Dll文件为:
HHOOK g_hHook;
HINSTANCE g_hinstDll;
FARPROC pfMessageBoxA;
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
BYTE OldMessageBoxACode[5],NewMessageBoxACode[5];
HMODULE hModule ;
DWORD dwIdOld,dwIdNew;
BOOL bHook=false;
void HookOn();
void HookOff();
BOOL init();
LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if(!init())
{
MessageBoxA(NULL,"Init","ERROR",MB_OK);
return(false);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
if(bHook) UnintallHook();
break;
}
return TRUE;
}
LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数
{
return(CallNextHookEx(g_hHook,nCode,wParam,lParam));
}
HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数
{
g_hinstDll=LoadLibrary("HookApi2.dll");
g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0);
if (!g_hHook)
{
MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK);
return(false);
}
return(true);
}
HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数
{
return(UnhookWindowsHookEx(g_hHook));
} BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令
{
hModule=LoadLibrary("user32.dll");
pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA");
if(pfMessageBoxA==NULL)
return false;
_asm
{
lea edi,OldMessageBoxACode
mov esi,pfMessageBoxA
cld
movsd
movsb
}
NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令
_asm
{
lea eax,MyMessageBoxA
mov ebx,pfMessageBoxA
sub eax,ebx
sub eax,5
mov dword ptr [NewMessageBoxACode+1],eax
}
dwIdNew=GetCurrentProcessId(); //得到所属进程的ID
dwIdOld=dwIdNew;
HookOn();//开始拦截
return(true);
} int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数
{
int nReturn=0;
HookOff();
nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType);
HookOn();
return(nReturn);
}
void HookOn()
{
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写
WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性
bHook=true;
}
void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA
{
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0);
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);
bHook=false;
}
//测试文件:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
if(!InstallHook())
{
MessageBoxA(NULL,"Hook Error!","Hook",MB_OK);
return 1;
}
MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见
if(!UninstallHook())
{
MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK);
return 1;
}
return 0;
}
大概啊。因为只有dll函数材能注入其它进程德空间,你的和序不可能注入其它进程德空间吧。 可是在我的那个合二为一的程序中是起作用的呀,只是在别的程序中不行。
另外,在我的程序中看起来的确是将代码注入到User32.dll中了,为什么rujor(rujor)说“你的和序不可能注入其它进程德空间吧”呢?dll和我的程序有什么区别呢? 一般是进程内hook在程序内,进程外hook要做成动态库。
....so many sites u can find via www.google.com...just use key of "hook api" ...Enjoy !
反正就是这个意思:
win32里与win16不同,所有内存(也可能是线程)都是独立(局部)的,相互之间不能影响。幸好DLL可以被不同的程序共同使用,所以微软用这个方法弥补了这个全局共享的问题。关于全局API HOOK的程序,我曾经做了一个,您可以下载:
ftp://pub:[email protected]/Hook和hotKey.rar
ftp://pub:[email protected]/Hook和hotKey源码.rar运行软件之前,请先看一下使用说明.
我这个菜鸟也就研究了一个星期,做了个程序,拿着这个程序到处卖分,真是不好意思。
不用给我分了!
你的这个例子是Hook的API函数吗?
我想实现的是对api函数的hook,不是对键盘和鼠标的hook:)谢谢!!
APIHook一直是使大家感兴趣的话题。屏幕取词,内码转化,屏幕翻译,中文平台等等都涉及到了此项技术。有很多文章涉及到了这项技术,但都闪烁其词不肯明明白白的公布。我仅在这里公布以下我用Delphi制作APIHook的一些心得。
通常的APIHOOK有这样几种方法:
1、自己写一个动态链接库,里面定义自己写的想取代系统的API。把这个动态链接库映射到2G以上的系统动态链接库所在空间,把系统动态链接库中的该API的指向修改指向自己的函数。这种方法的好处就是可以取代系统中运行全部程序的该API。但他有个局限,就是只适用于Win9x。(原因是NT中动态链接库不是共享的,每个进程都有自己的一份动态链接库在内存中的映射)
2、自己写一个动态链接库,里面定义自己写得象替代系统的API。把这个动态链接库映射到进程的空间里。将该进程对API的调用指向自己写的动态链接库。这种方法的好处是可以选择性的替代哪个进程的API。而且适用于所有的Windows*作系统。
这里我选用的是第二种方法。
第二种方法需要先了解一点PE文件格式的知识。
首先是一个实模式的的DOS文件头,是为了保持和DOS的兼容。
接着是一个DOS的代理模块。你在纯DOS先运行Win32的可执行文件,看看是不是也执行了,只是显示的的是一行信息大意是说该Windows程序不能在DOS实模式下运行。
然后才是真正意义上的Windows可执行文件的文件头。它的具体位置不是每次都固定的。是由文件偏移$3C决定的。我们要用到的就是它。
如果我们在程序中调用了一个MessageBoxA函数那么它的实现过程是这样的。他先调用在本进程中的MessageBoxA函数然后才跳到动态链接库的MessageBoxA的入口点。即:
call messageBoxA(0040106c)
jmp dword ptr [_jmp_MessageBoxA@16(00425294)]
其中00425294的内容存储的就是就是MessageBoxA函数的入口地址。如果我们做一下手脚,那么......
那就开始吧!
我们需要定义两个结构
type
PImage_Import_Entry = ^Image_Import_Entry;
Image_Import_Entry = record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion: Word;
MinorVersion: Word;
Name: DWORD;
LookupTable: DWORD;
end;
type
TImportCode = packed record
JumpInstruction: Word; file: //定义跳转指令jmp
AddressOfPointerToFunction: ^Pointer; file: //定义要跳转到的函数
end;
PImportCode = ^TImportCode;
然后是确定函数的地址。
function LocateFunctionAddress(Code: Pointer): Pointer;
var
func: PImportCode;
begin
Result := Code;
if Code = nil then exit;
try
func := code;
if (func.JumpInstruction = $25FF) then
begin
Result := func.AddressOfPointerToFunction^;
end;
except
Result := nil;
end;
end;
参数Code是函数在进程中的指针,即那条Jmp XXX的指令。$25FF就是跳转指令的机器码。
再下一篇我会讲如何替换下那个XXX的内容,让他跳到你想去的地方。
)
在这里我将要实现转跳。有人说修改内存内容要进入Ring 0 才可以。可是Windows本身提供了一个写内存的指令WriteProcessMemory。有了这把利器,我们几乎无所不能。如游戏的修改等在这里我们只谈APIHOOK。
function RepointFunction(OldFunc, NewFunc: Pointer): Integer;
var
IsDone: TList;
function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry;
RVA: DWORD;
Func: ^Pointer;
DLL: string;
f: Pointer;
written: DWORD;
begin
Result := 0;
Dos := Pointer(hModule);
if IsDone.IndexOf(Dos) >= 0 then exit;
IsDone.Add(Dos); OldFunc := LocateFunctionAddress(OldFunc); if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit;
if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
NT := Pointer(Integer(Dos) + dos._lfanew); RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress; if RVA = 0 then exit;
ImportDesc := pointer(integer(Dos) + RVA);
while (ImportDesc^.Name <> 0) do
begin
DLL := PChar(Integer(Dos) + ImportDesc^.Name);
RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
while Func^ <> nil do
begin
f := LocateFunctionAddress(Func^);
if f = OldFunc then
begin
WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
if Written > 0 then Inc(Result);
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
end; begin
IsDone := TList.Create;
try
Result := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);
finally
IsDone.Free;
end;
end;
有了这两个函数我们几乎可以更改任何API函数。
我们可以先写一个DLL文件。我这里以修改Text相关函数为例:
先定义几个函数:
type
TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
var
OldTextOutA: TTextOutA;
OldTextOutW: TTextOutW;
OldTextOut: TTextOut;
OldDrawTextA: TDrawTextA;
OldDrawTextW: TDrawTextW;
OldDrawText: TDrawText;
......
function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutA(DC, X, Y, 'ABC', length('ABC'));
end; function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutW(DC, X, Y, 'ABC', length('ABC'));
end; function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
begin
OldTextOut(DC, X, Y, 'ABC', length('ABC'));
end; function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextA(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end; function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextW(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end; function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawText(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end; 调用时我们要把原来的函数地址保存下来:
if @OldTextOutA = nil then
@OldTextOutA := LocateFunctionAddress(@TextOutA);
if @OldTextOutW = nil then
@OldTextOutW := LocateFunctionAddress(@TextOutW);
if @OldTextOut = nil then
@OldTextOut := LocateFunctionAddress(@TextOut);
if @OldDrawTextA = nil then
@OldDrawTextA := LocateFunctionAddress(@DrawTextA);
if @OldDrawTextW = nil then
@OldDrawTextW := LocateFunctionAddress(@DrawTextW);
if @OldDrawText = nil then
@OldDrawText := LocateFunctionAddress(@DrawText);
然后很顺其自然的用自己的函数替换掉原来的函数
RepointFunction(@OldTextOutA, @MyTextOutA);
RepointFunction(@OldTextOutW, @MyTextOutW);
RepointFunction(@OldTextOut, @MyTextOut);
RepointFunction(@OldDrawTextA, @MyDrawTextA);
RepointFunction(@OldDrawTextW, @MyDrawTextW);
RepointFunction(@OldDrawText, @MyDrawText);
在结束时不要忘记恢复原来函数的入口,要不然你会死得很难看哟!好了我们在写一个Demo程序。你会说怎么文字没有变成ABC呀?是呀,你要刷新一下才行。最小化然后在最大化。看看变了没有。
要不然你就写代码刷新一下好了。至于去拦截其他进程的API那就用SetWindowsHookEx写一个其他的钩子将DLL映射进去就行了,我就不再浪费口水了。
掌握了该方法你几乎无所不能。你可以修改其它程序。你可以拦截Createwindow等窗口函数改变其他程序的窗口形状、你还可以入侵其它的程序,你还可以......嘿嘿。干了坏事别招出我来就行了。
我还写了个例子,请在CSDN上下载。
“至于去拦截其他进程的API那就用SetWindowsHookEx写一个其他的钩子将DLL映射进去就行了,我就不再浪费口水了”
如他所说,我想做的就是如何将钩子dll映射到当前的所有进程的地址空间中,应该如何实现?谢谢nevergrief(孤独骑士),再想想办法,等问题解决了单独开帖子给你分,谢谢!
http://www.csdn.net/develop/article/12/12283.shtm另外,不知您是否对打印有研究?小弟正着急呢,帮忙看看:
http://www.vckbase.com/bbs2/viewtopic2.asp?id=85982
with C/C++.
Just include this file and you can start using the functions. by yoda*/#ifndef __ForceLibraryHeader__
#define __ForceLibraryHeader__// the dll prototypes
typedef DWORD (WINAPI* fForceLibrary)(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
typedef BOOL (WINAPI* fTrapEntry)(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
typedef BOOL (WINAPI* fForceLibraryDBG)(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
typedef DWORD (WINAPI* fPerformCleanup)(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// functions
BOOL LoadFL();
DWORD ForceLibrary(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
BOOL TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
BOOL ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
DWORD PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// constants
const CHAR* szDllName = "ForceLibrary.dll";
const PSTR szFunctNameFL = "ForceLibrary";
const PSTR szFunctNameTE = "TrapEntry";
const PSTR szFunctNameFLDBG = "ForceLibraryDBG";
const PSTR szFunctNamePC = "PerformCleanup";const CHAR* szError = "ERROR";
const DWORD dwMsgFlags = MB_ICONERROR | MB_TASKMODAL;
const CHAR* szDllNotFound = "ForceLibrary.dll wasn't found !";
const CHAR* szGetProcError = "Error during Dll initialization !";// variables
fForceLibrary _ForceLibrary;
fTrapEntry _TrapEntry;
fForceLibraryDBG _ForceLibraryDBG;
fPerformCleanup _PerformCleanup;HANDLE hFL = 0;
BOOL LoadFL()
{
hFL = LoadLibrary(szDllName);
if (!hFL)
{
MessageBox(0,szDllNotFound,szError,dwMsgFlags);
return FALSE;
}
_ForceLibrary = (fForceLibrary)GetProcAddress((HMODULE)hFL,szFunctNameFL);
_TrapEntry = (fTrapEntry)GetProcAddress((HMODULE)hFL,szFunctNameTE);
_ForceLibraryDBG = (fForceLibraryDBG)GetProcAddress((HMODULE)hFL,szFunctNameFLDBG);
_PerformCleanup = (fPerformCleanup)GetProcAddress((HMODULE)hFL,szFunctNamePC); if (!_ForceLibrary ||
!_TrapEntry ||
!_ForceLibraryDBG ||
!_PerformCleanup)
{
MessageBox(0,szGetProcError,szDllName,dwMsgFlags);
return FALSE;
}
return TRUE;
}
BOOL TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
{
if (!hFL)
if (!LoadFL())
return FALSE;
return _TrapEntry(dwEntryPoint,pPI);
}BOOL ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
{
if (!hFL)
if (!LoadFL())
return FALSE;
return _ForceLibraryDBG(szTargetLib,dwEntryPoint,pPI);
}DWORD PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
{
if (!hFL)
if (!LoadFL())
return 0;
return _PerformCleanup(dwEntryPoint,pPI);
} #endif
///// -=[ ForceLibrary.dll ]=-
//// by yoda/f2f
/// version: 1.2
//
// You are able to use *parts* of this source code in your own programs
// if you mention my name.
// Please report any bugs/comments/suggestions to [email protected]
// Have fun.
//#include <windows.h>
#include <tlhelp32.h>
#include <stddef.h>
#include "th32.h"#pragma pack(1) // very important !// this code structs load the dll
typedef struct
{
//BYTE Int3;
BYTE PushOpc; // 0x68 = push (dword)
DWORD PushAddr; // address of dll name
BYTE CallOpc; // 0xE8 = call (dword)
DWORD CallAddr; // address of LoadLibraryAPI
WORD jmp_$; // 0xEBFE = jmp eip
char LibPath[MAX_PATH]; // path of the dll to load
} sLibLoadCode;typedef struct
{
//BYTE Int3;
BYTE PushOpc; // 0x68 = push (dword)
DWORD PushAddr; // address of dll name
BYTE CallOpc; // 0xE8 = call (dword)
DWORD CallAddr; // address of LoadLibraryAPI
BYTE RetOpc; // 0xC2 = ret (word)
WORD RetValue; // return number
char LibPath[MAX_PATH]; // path of the dll to load
} sLibLoadCodeNT;typedef struct
{
BYTE PushOpc; // 0x68 = push (dword)
DWORD PushAddr; // address of dll name
BYTE CallOpc; // 0xE8 = call (dword)
DWORD CallAddr; // address of LoadLibraryAPI
BYTE Int3; // end of code
char LibPath[256]; // path of the dll to load
} sLibLoadCodeDBG;typedef struct
{
DWORD dwImageBase;
DWORD dwSizeOfImage;
DWORD dwEntryPointVA;
} sProcessPEInfo;typedef DWORD (WINAPI* _CodeEntry)(PVOID);// the functions
BOOL InitCodeStruct(sLibLoadCode *LibLoaderCode,
sLibLoadCodeNT *LibLoaderCodeNT,
CHAR* szTargetLib,
DWORD dwCodeStart);
BOOL InitCodeStructDBG(sLibLoadCodeDBG &LibLoaderCode,CHAR* szTargetLib,DWORD dwCodeStart);
DWORD GetProcessEntryPoint(DWORD PID);
BOOL ForceLibrary95(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
BOOL ForceLibraryNT(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
extern "C" BOOL WINAPI TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
extern "C" BOOL WINAPI ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
extern "C" DWORD WINAPI PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// constants
const DWORD LOADCODESIZEDBG = sizeof(sLibLoadCodeDBG);
const DWORD HEADER_SIZE = 0x2000;
const BYTE Int3 = 0xCC;// global variables
sLibLoadCodeDBG LibLoadCodeDBG;
DWORD dwLibBase;
DWORD dwCodeStart,dwCodeEnd,dwBytesWritten,dwBytesRead;
CONTEXT TestRegs;VOID* pCodeEntry;
DWORD dwOldProt,dwNewProt;
CONTEXT Regs,InitRegs;
BYTE bOrgEntry;DWORD ForceLibrary(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo)
{
DWORD dwWinVer = GetVersion(); // get the highest bit
dwWinVer = dwWinVer >> 31; if (!dwWinVer)
if (ForceLibraryNT(szLibraryPath,pProcInfo))
return dwLibBase;
else
return 0;
else
if (ForceLibrary95(szLibraryPath,pProcInfo))
return dwLibBase;
else
return 0;
}BOOL InitCodeStruct(sLibLoadCode *LibLoaderCode,
sLibLoadCodeNT *LibLoaderCodeNT,
CHAR* szTargetLib,
DWORD dwCodeStart)
{
DWORD dwLoadLibApiAddr; dwLoadLibApiAddr = (DWORD)GetProcAddress(
GetModuleHandle("kernel32.dll"),
"LoadLibraryA");
if (!dwLoadLibApiAddr)
return FALSE;
if (LibLoaderCode)
{
//LibLoaderCode->Int3 = Int3;
LibLoaderCode->PushOpc = 0x68;
LibLoaderCode->CallOpc = 0xE8;
LibLoaderCode->CallAddr = dwLoadLibApiAddr - dwCodeStart -
offsetof(sLibLoadCode,jmp_$);
strcpy(LibLoaderCode->LibPath,szTargetLib);
LibLoaderCode->PushAddr = dwCodeStart + offsetof(sLibLoadCode,LibPath);
LibLoaderCode->jmp_$ = 0xFEEB;
}
else
{
//LibLoaderCodeNT->Int3 = Int3;
LibLoaderCodeNT->PushOpc = 0x68;
LibLoaderCodeNT->CallOpc = 0xE8;
LibLoaderCodeNT->CallAddr = dwLoadLibApiAddr - dwCodeStart -
offsetof(sLibLoadCodeNT, RetOpc);
strcpy(LibLoaderCodeNT->LibPath,szTargetLib);
LibLoaderCodeNT->PushAddr = dwCodeStart + offsetof(sLibLoadCodeNT, LibPath);
LibLoaderCodeNT->RetOpc = 0xC2;
LibLoaderCodeNT->RetValue = 0x0004;
}
return TRUE;
}BOOL InitCodeStructDBG(sLibLoadCodeDBG &LibLoaderCode,CHAR* szTargetLib,DWORD dwCodeStart)
{
DWORD dwLoadLibApiAddr; LibLoaderCode.Int3 = Int3;
LibLoaderCode.PushOpc = 0x68;
LibLoaderCode.CallOpc = 0xE8;
dwLoadLibApiAddr = (DWORD)GetProcAddress(
GetModuleHandle("kernel32.dll"),
"LoadLibraryA");
if (!dwLoadLibApiAddr)
return FALSE;
LibLoaderCode.CallAddr = dwLoadLibApiAddr - dwCodeStart - offsetof(sLibLoadCodeDBG,Int3);
strcpy(LibLoaderCode.LibPath,szTargetLib);
LibLoaderCode.PushAddr = dwCodeStart + offsetof(sLibLoadCodeDBG,LibPath);
return TRUE;
}// returns...
// 0 - error
DWORD GetProcessEntryPoint(DWORD PID)
{
HANDLE hSnap;
MODULEENTRY32 ModuleInfo;
PROCESSENTRY32 ProcInfo;
sProcessPEInfo ProcPEInfo;
CHAR ProcPath[256];
DWORD dwMemSize,dwPEHeaderAddr;
VOID* pHeader;
HANDLE hProc; // get ToolHelp32 addresses
if (!GetTh32())
return FALSE; // I - get the process filename
hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hSnap == INVALID_HANDLE_VALUE)
return 0; // init the ProcInfo struct
ZeroMemory(&ProcInfo,sizeof(ProcInfo));
ProcInfo.dwSize = sizeof(ProcInfo); // find the to the PID corresponding file path
_Process32First(hSnap,&ProcInfo);
ProcPath[0] = 0;
while (_Process32Next(hSnap,&ProcInfo))
if (ProcInfo.th32ProcessID == PID)
strcpy((LPTSTR)&ProcPath,ProcInfo.szExeFile);
CloseHandle(hSnap);
if (ProcPath[0] == 0)
return 0; // II - find the ImageBase/SizeOfImage
hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,PID);
if (hSnap == INVALID_HANDLE_VALUE)
return 0; // init the ModuleInfo and the ProcPEInfo struct
ZeroMemory(&ModuleInfo,sizeof(ModuleInfo));
ModuleInfo.dwSize = sizeof(ModuleInfo);
ZeroMemory(&ProcPEInfo,sizeof(ProcPEInfo)); _Module32First(hSnap,&ModuleInfo);
if (stricmp((LPCTSTR)&ModuleInfo.szExePath,(LPCTSTR)&ProcPath) == 0)
{
ProcPEInfo.dwImageBase = (DWORD)ModuleInfo.modBaseAddr;
ProcPEInfo.dwSizeOfImage = ModuleInfo.modBaseSize;
}
while (_Module32Next(hSnap,&ModuleInfo))
{
if (stricmp((LPCTSTR)&ModuleInfo.szExePath,(LPCTSTR)&ProcPath) == 0)
{
ProcPEInfo.dwImageBase = (DWORD)ModuleInfo.modBaseAddr;
ProcPEInfo.dwSizeOfImage = ModuleInfo.modBaseSize;
}
}
if (ProcPEInfo.dwImageBase == 0)
return 0; // get the EntryPoint
if (ProcPEInfo.dwSizeOfImage < HEADER_SIZE)
dwMemSize = ProcPEInfo.dwSizeOfImage;
else
dwMemSize = HEADER_SIZE;
if (!(hProc = OpenProcess(PROCESS_VM_READ,FALSE,PID)))
return 0;
if (!(pHeader = GlobalAlloc(GMEM_FIXED,dwMemSize)))
return 0;
if (!ReadProcessMemory(
hProc,
(PVOID)ProcPEInfo.dwImageBase,
pHeader,
dwMemSize,
&dwBytesRead))
{
GlobalFree(pHeader);
return 0;
}
if (((PIMAGE_DOS_HEADER)pHeader)->e_magic != IMAGE_DOS_SIGNATURE)
{
GlobalFree(pHeader);
return 0;
}
dwPEHeaderAddr = ((PIMAGE_DOS_HEADER)pHeader)->e_lfanew;
if (((PIMAGE_NT_HEADERS)(dwPEHeaderAddr + (DWORD)pHeader))->Signature !=
IMAGE_NT_SIGNATURE)
{
GlobalFree(pHeader);
return 0;
}
ProcPEInfo.dwEntryPointVA = ((PIMAGE_NT_HEADERS)(dwPEHeaderAddr + (DWORD)pHeader))->OptionalHeader \
.AddressOfEntryPoint + ProcPEInfo.dwImageBase;
GlobalFree(pHeader);
return ProcPEInfo.dwEntryPointVA;
}BOOL ForceLibrary95(char* szLibraryPath, PROCESS_INFORMATION* pProcInfo)
{
DWORD dwEntryPoint,dwEWRProt;
sLibLoadCode LibLoadCode; InitRegs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
if (!GetThreadContext(pProcInfo->hThread,&InitRegs))
return FALSE;
if (!(dwEntryPoint = GetProcessEntryPoint(pProcInfo->dwProcessId)))
return FALSE; // init the LibLoadCode struct
if (!InitCodeStruct(&LibLoadCode, NULL, szLibraryPath, dwEntryPoint))
return FALSE; // save the code at the EntryPoint
pCodeEntry = GlobalAlloc(GMEM_FIXED, sizeof(LibLoadCode));
if (!pCodeEntry)
return FALSE;
VirtualProtectEx(
pProcInfo->hProcess,
(VOID*)dwEntryPoint,
sizeof(LibLoadCode),
PAGE_EXECUTE_READWRITE,
&dwOldProt);
if (!ReadProcessMemory(
pProcInfo->hProcess,
(VOID*)dwEntryPoint,
pCodeEntry,
sizeof(LibLoadCode),
&dwBytesRead))
{
GlobalFree(pCodeEntry);
return FALSE;
}
// write the loader code to the EntryPoint
if (!WriteProcessMemory(
pProcInfo->hProcess,
(VOID*)dwEntryPoint,
&LibLoadCode,
sizeof(LibLoadCode),
&dwBytesWritten))
{
GlobalFree(pCodeEntry);
return FALSE;
} // execute the copied code
Regs = InitRegs;
Regs.Eip = dwEntryPoint;
ResumeThread(pProcInfo->hThread); // wait until the thread finishes
dwCodeEnd = dwEntryPoint + offsetof(sLibLoadCode,jmp_$);
TestRegs.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
do
{
Sleep(50);
GetThreadContext(pProcInfo->hThread,&TestRegs);
} while (TestRegs.Eip != dwCodeEnd);
dwLibBase = TestRegs.Eax; // suspend the thread and restore all !
SuspendThread(pProcInfo->hThread);
if (!WriteProcessMemory(
pProcInfo->hProcess,
(VOID*)dwEntryPoint,
pCodeEntry,
sizeof(LibLoadCode),
&dwBytesWritten))
{
GlobalFree(pCodeEntry);
return FALSE;
}
GlobalFree(pCodeEntry);
VirtualProtectEx(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
dwOldProt,
&dwEWRProt);
InitRegs.Eip = dwEntryPoint;
if (!SetThreadContext(pProcInfo->hThread,&InitRegs))
return FALSE;
return TRUE;
}BOOL ForceLibraryNT(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo)
{
sLibLoadCodeNT LibLoadCode;
DWORD dwRemoteThreadID;
HANDLE hRemoteThread;
_CodeEntry CodeEntry;
// import NT only stuff manually
HMODULE kernel = GetModuleHandle("kernel32.dll"); typedef LPVOID (WINAPI*VirtualAllocExFunc)(
HANDLE hProcess, // process to allocate memory
LPVOID lpAddress, // desired starting address
SIZE_T dwSize, // size of region to allocate
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
VirtualAllocExFunc VirtualAllocExPtr = (VirtualAllocExFunc)GetProcAddress(kernel,"VirtualAllocEx"); typedef BOOL (WINAPI*VirtualFreeExFunc)(
HANDLE hProcess, // handle to process
LPVOID lpAddress, // starting address of memory region
SIZE_T dwSize, // size of memory region
DWORD dwFreeType // operation type
);
VirtualFreeExFunc VirtualFreeExPtr = (VirtualFreeExFunc)GetProcAddress(kernel,"VirtualFreeEx"); if(!VirtualFreeExPtr || !VirtualAllocExPtr)
{
MessageBox(0,"couldnt import virtualallocex",0,0);
ExitProcess(1);
} // get some mem in the target's process memory
dwCodeStart = (DWORD)VirtualAllocExPtr(
pProcInfo->hProcess,
NULL,
sizeof(LibLoadCode),
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!dwCodeStart)
return FALSE; // init the LibLoadCode struct
if (!InitCodeStruct(0, &LibLoadCode, szLibraryPath, dwCodeStart))
{
VirtualFreeExPtr(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
MEM_DECOMMIT);
return FALSE;
} // copy the code into the allocated mem
if (!WriteProcessMemory(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
&LibLoadCode,
sizeof(LibLoadCode),
&dwBytesWritten))
{
VirtualFreeExPtr(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
MEM_DECOMMIT);
return FALSE;
} // execute it
CodeEntry = (_CodeEntry)dwCodeStart;
if (!(hRemoteThread = CreateRemoteThread(
pProcInfo->hProcess,
NULL,
0,
CodeEntry,
NULL,
0,
&dwRemoteThreadID)))
{
VirtualFreeExPtr(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
MEM_DECOMMIT);
return FALSE;
}
WaitForSingleObject(hRemoteThread, INFINITE);
if (!GetExitCodeThread(hRemoteThread, &dwLibBase))
{
VirtualFreeExPtr(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
MEM_DECOMMIT);
return FALSE;
} // clean up
VirtualFreeExPtr(
pProcInfo->hProcess,
(VOID*)dwCodeStart,
sizeof(LibLoadCode),
MEM_DECOMMIT);
CloseHandle(hRemoteThread); if (dwLibBase)
return TRUE;
else
return FALSE;
}extern "C" BOOL WINAPI TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
{
// simply set a 0CCh at the EntryPoint
VirtualProtectEx(
pPI->hProcess,
(VOID*)dwEntryPoint,
1,
PAGE_EXECUTE_READWRITE,
&dwOldProt);
if (!ReadProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
(VOID*)&bOrgEntry,
1,
&dwBytesRead))
return FALSE;
if (!WriteProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
(VOID*)&Int3,
1,
&dwBytesWritten))
return FALSE;
VirtualProtectEx(
pPI->hProcess,
(VOID*)dwEntryPoint,
1,
dwOldProt,
&dwNewProt);
return TRUE;
}extern "C" BOOL WINAPI ForceLibraryDBG(CHAR* szTargetLib,
DWORD dwEntryPoint,
PROCESS_INFORMATION *pPI)
{
// save the regs
Regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
if (!GetThreadContext(pPI->hThread,&Regs))
return FALSE;
Regs.Eip = dwEntryPoint;
InitRegs = Regs; // init the LibLoadCodeDBG struct
if (!InitCodeStructDBG(LibLoadCodeDBG,szTargetLib,dwEntryPoint))
return FALSE; VirtualProtectEx(
pPI->hProcess,
(VOID*)dwEntryPoint,
LOADCODESIZEDBG,
PAGE_EXECUTE_READWRITE,
&dwOldProt); // restore the EntryPoint-byte
if (!WriteProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
&bOrgEntry,
1,
&dwBytesWritten))
return FALSE; // save the code at the EntryPoint
pCodeEntry = GlobalAlloc(GMEM_FIXED,LOADCODESIZEDBG);
if (!pCodeEntry)
return FALSE;
if (!ReadProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
pCodeEntry,
LOADCODESIZEDBG,
&dwBytesRead))
{
GlobalFree(pCodeEntry);
return FALSE;
}
// write the loader code to the EntryPoint and restore protection of the code page
if (!WriteProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
&LibLoadCodeDBG,
LOADCODESIZEDBG,
&dwBytesWritten))
{
GlobalFree(pCodeEntry);
return FALSE;
} // prepare the execution of the copied code
SetThreadContext(pPI->hThread,&Regs);
return TRUE;
}extern "C" DWORD WINAPI PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
{
// grab the result of the "LoadLibraryA" call
GetThreadContext(pPI->hThread,&Regs);
dwLibBase = Regs.Eax; // restore all !
if (!WriteProcessMemory(
pPI->hProcess,
(VOID*)dwEntryPoint,
pCodeEntry,
LOADCODESIZEDBG,
&dwBytesWritten))
{
GlobalFree(pCodeEntry);
return 0;
}
GlobalFree(pCodeEntry);
VirtualProtectEx(
pPI->hProcess,
(VOID*)dwEntryPoint,
LOADCODESIZEDBG,
dwOldProt,
&dwNewProt);
if (!SetThreadContext(pPI->hThread,&InitRegs))
return 0;
return dwLibBase;
}
#define __TH32_h__#include <windows.h>
#include <tlhelp32.h>// ToolHelp32 function prototypes
typedef HANDLE (WINAPI* fCreateToolhelp32Snapshot)
(
DWORD dwFlags,
DWORD th32ProcessID
);typedef BOOL (WINAPI* fProcess32First)
(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
typedef BOOL (WINAPI* fProcess32Next)
(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);typedef BOOL (WINAPI* fModule32First)
(
HANDLE hSnapshot,
LPMODULEENTRY32 lpme
);
typedef BOOL (WINAPI* fModule32Next)
(
HANDLE hSnapshot,
LPMODULEENTRY32 lpme
);extern fCreateToolhelp32Snapshot _CreateToolhelp32Snapshot;
extern fProcess32First _Process32First;
extern fProcess32Next _Process32Next;
extern fModule32First _Module32First;
extern fModule32Next _Module32Next;BOOL GetTh32();#endif
//anotherfile//
// TH32.c: loads dynamically the ToolHelp32 API's because they
// aren't available on NT4 ! Much thanks goes to ELiCZ
// for putting my attention on that fact.
//#include "th32.h"
#pragma pack(1) // very important !// global variables
fCreateToolhelp32Snapshot _CreateToolhelp32Snapshot;
fProcess32First _Process32First;
fProcess32Next _Process32Next;
fModule32First _Module32First;
fModule32Next _Module32Next;BOOL GetTh32()
{
HINSTANCE hKrnl; // get kernel32 base
hKrnl = LoadLibrary("Kernel32.dll");
if (!hKrnl)
return FALSE; // get th32 addresses
_CreateToolhelp32Snapshot = (fCreateToolhelp32Snapshot)GetProcAddress(
hKrnl, "CreateToolhelp32Snapshot");
_Process32First = (fProcess32First)GetProcAddress(hKrnl, "Process32First");
_Process32Next = (fProcess32Next)GetProcAddress(hKrnl, "Process32Next");
_Module32First = (fModule32First)GetProcAddress(hKrnl, "Module32First");
_Module32Next = (fModule32Next)GetProcAddress(hKrnl, "Module32Next"); if (!_CreateToolhelp32Snapshot ||
!_Process32First ||
!_Process32Next ||
!_Module32First ||
!_Module32Next)
return FALSE;
return TRUE;
}
#include "stdio.h"
#include "ForceLib.h"#pragma pack(1) // very important !HINSTANCE mainInstance;bool fileExists(const char* filename)
{
WIN32_FIND_DATA finddata;
HANDLE handle = FindFirstFile(filename,&finddata);
return (handle!=INVALID_HANDLE_VALUE);
}//#define OGC_DEBUG
#undef OGC_DEBUG//==============================================================================
bool promptForFile( char* retFile, const char* tip, char* filter, char* title, bool save, HWND hWnd )
{
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.hInstance = mainInstance;
ofn.nFilterIndex = 1;
ofn.lpstrFile = retFile;
ofn.nMaxFile = 256;
ofn.lpstrInitialDir = tip;
//====
ofn.lpstrFilter = filter;
ofn.lpstrTitle = title; strcpy( retFile, tip ); bool status;
if( save )
{
ofn.Flags = OFN_OVERWRITEPROMPT;
status = (GetSaveFileName(&ofn)!=0);
} else
{
ofn.Flags = OFN_FILEMUSTEXIST;
status = (GetOpenFileName(&ofn)!=0);
}
return status;
}STARTUPINFO SI;
PROCESS_INFORMATION PI;//==================================================================================
bool isApplogAlreadyDisabled()
{
HKEY l_hKey;
DWORD l_UseProfile;
DWORD l_dwBufLen = 4; DWORD l_ret = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Defrag\\AppStartParams",
0,KEY_QUERY_VALUE, &l_hKey);
if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; } l_ret = RegQueryValueEx(l_hKey,"UseProfile",NULL,NULL,(LPBYTE)&l_UseProfile,&l_dwBufLen);
if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; } RegCloseKey(l_hKey);
return (l_UseProfile==0);
}//==================================================================================
bool isOnWindowsDrive(char* file)
{
// check for windows drive = hl drive
char windir[400];
GetWindowsDirectory(windir,390);
if( file[1]==':' && windir[1]==':' && tolower(file[0])==tolower(windir[0]) ) return true;
else return false;
}//==================================================================================
void unHideApplog()
{
char applogdir[400];
GetWindowsDirectory(applogdir,390);
strcat(applogdir,"\\Applog");
SetFileAttributes( applogdir, FILE_ATTRIBUTE_NORMAL );
}////==================================================================================
//void ErrorExit(char* text)
//{
// MessageBox(0,text,0,0);
// ExitProcess(1);
//}
//
////==================================================================================
//void disableApplog()
//{
// HKEY hk;
//
// if (RegCreateKey(
// HKEY_LOCAL_MACHINE,
// "Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Defrag\\AppStartParams",&hk
// ) != ERROR_SUCCESS )
// {
// ErrorExit("Registry access error. 1");
// }
//
// DWORD NewValue = 0;
// if (RegSetValueEx(hk,"UseProfile",0,REG_DWORD,(BYTE*)&NewValue,4) != ERROR_SUCCESS)
// {
// ErrorExit("Registry access error. 2");
// }
//}////==================================================================================
//void cleanupApplog()
//{
// WIN32_FIND_DATA findData;
// HANDLE hFindFile;
// char* fileName = findData.cFileName;
//
// char searchPattern[400];
// GetWindowsDirectory(searchPattern,390);
// strcat(searchPattern,"\\Applog\\*.*");
//
// hFindFile = FindFirstFile( searchPattern, &findData );
// if( hFindFile == INVALID_HANDLE_VALUE){ return; }
// do{
// if(strcmp(fileName,".") && strcmp(fileName,".."))
// {
// char fullname[400];
// strcpy(fullname,searchPattern);
// strcpy(fullname + strlen(fullname)-3,fileName);
// DeleteFile(fullname);
// }
// } while( FindNextFile(hFindFile,&findData) );
//}////==================================================================================
void applogFix()
{
// check for NT
bool IsNT = ((HIWORD(::GetVersion()) & 0x8000) == 0);
#ifdef OGC_DEBUG
IsNT = false;
#endif
if(IsNT) return; // make it easier for users to find applog
unHideApplog();// if(!isApplogAlreadyDisabled())
// {
// DWORD ret = MessageBox( 0,
// "OGC Hook has detected that you are running\n"
// "Windows 98 or Windows ME, and have Half-Life installed\n"
// "on the same drive as your Operating System.\n"
// "In order to avoid server side detection by scanning\n"
// "for applog files, OGC Hook can disable the Applog Feature.\n"
// "\nDo you want to disable Applog? (required)"
// ,
// "[OGC] Applog Disabling",
// MB_YESNO|MB_ICONQUESTION
// );
// if( ret != IDYES )
// {
// MessageBox(0,
// "You've chosen to leave Applog enabled.\n"
// "If you want to uninstall OGC Hook, you \n"
// "might want to browse to your WINDOWS\\Applog\n"
// "folder and delete OGC related files manually\n\n"
// "OGC Hook will now quit!\n"
// , "[OGC] Info", MB_OK );
// ExitProcess(0);
// }
//
// // deleting a few files can take ages in win9x. inform the user.
// MessageBox(0,"OGC Hook will now disable Applog"
// " file creation,\nand cleanup the WINDOWS\\Applog folder\n"
// "This may take some time" , "[OGC] Info",MB_OK);
//
// disableApplog();
// cleanupApplog();
//
// MessageBox(0,"OGC Hook is done with Applog \n"
// "cleanup. Half-Life will now be startetd.",
// "[OGC] Info",MB_OK);
// }
// else
// {
// cleanupApplog();
// }
}//==================================================================================
{
while(a[strlen(a)-1]=='\x0D' || a[strlen(a)-1]=='\x0A' ) a[strlen(a)-1]=0;
}
//==================================================================================
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
mainInstance = hInstance; // setup
char hookEXE [400] = ""; // "c:\\program files\\ogc hook\\notepad.exe"
char hookDLL [400] = ""; // "c:\\program files\\ogc hook\\notepad.dll"
char hookINI [400] = ""; // "c:\\program files\\ogc hook\\notepad.ini"
char hlCmdLine[400] = "";
char hlEXE [400] = "";
GetModuleFileName(0,hookEXE,390);
int len = strlen(hookEXE);
strcpy(hookDLL,hookEXE);
strcpy(hookINI,hookEXE);
hookDLL[len-3]='d';hookDLL[len-2]='l';hookDLL[len-1]='l';
hookINI[len-3]='i';hookINI[len-2]='n';hookINI[len-1]='i'; // file check
#ifndef OGC_DEBUG
if( !fileExists(hookDLL) ) {
MessageBox(0,hookDLL,"DLL NOT FOUND",MB_ICONERROR|MB_TOPMOST);
return 1;
}
#endif // try to get hl path out of the ini
bool success = false;
do{
FILE* file = fopen(hookINI,"r");
if(file)
{
fgets(hlEXE ,390,file);hlEXE[398]=0; removeTrailingCRLF(hlEXE);
fclose(file);
} if(!fileExists(hlEXE))
{
MessageBox(0,"Please point me to your HL/CS executable,\nhl.exe or cstrike.exe","[OGC] Request",MB_ICONEXCLAMATION);
bool ok = promptForFile( hlEXE, "c:\\sierra\\half-life\\hl.exe",
"hl.exe or cstrike.exe\0hl.exe;cstrike.exe\0",
"Show me your HL/CS Directory", false, 0);
if(!ok) { return 0; }
file = fopen(hookINI,"w");
if(file)
{
fprintf(file,"%s\x0D\x0A",hlEXE);
fclose(file);
} else {
MessageBox(0,hookINI,"write error",0);
break;
}
if(fileExists(hlEXE)) success = true;
}
else
{
success = true;
} } while(!success); if( !strcmpi(hlEXE,hookEXE) )
{
MessageBox(0,"cannot start myself","Error",MB_ICONEXCLAMATION);
DeleteFile(hookINI);
return 1;
} // disable applog for win9x
#ifndef OGC_DEBUG
if( isOnWindowsDrive(hlEXE) ) applogFix();
#else
applogFix();
#endif
// command line
if(!strstr(lpCmdLine,"-game")) strcpy(hlCmdLine," -game cstrike ");
strcat(hlCmdLine,lpCmdLine); // start the shit !
ZeroMemory(&SI,sizeof(STARTUPINFO));
ZeroMemory(&PI,sizeof(PROCESS_INFORMATION));
SI.cb = sizeof(STARTUPINFO); // set the right directory:
char hlDir[400];
strcpy(hlDir,hlEXE);
char* pos = hlDir+strlen(hlDir);
while(pos>=hlDir && *pos!='\\') --pos;
*pos = 0;
char* hlBaseFileName = pos+1;
SetCurrentDirectory(hlDir);
if (!CreateProcess(hlBaseFileName,hlCmdLine,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&SI,&PI))
{
MessageBox(0,"Cannot create the Halflife Process!","[OGC] Error",MB_ICONERROR|MB_TOPMOST);
return -1;
}
// call the dll function
if (!ForceLibrary(hookDLL,&PI))
{
MessageBox(0,"Injection failed.","[OGC] Error",MB_ICONERROR|MB_TOPMOST);
TerminateProcess(PI.hProcess,-1);
return -1;
} // let the main thread run
ResumeThread(PI.hThread);
// WaitForSingleObject(PI.hProcess,INFINITE); // clean up
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
return 0;
}
这个例子是把dll,inject 到某个进程中去的功能希望能有帮助,对了这个是cs的做弊器,各位不会不知道吧。
ftp://pub:[email protected]
好吗?同时加上几句简单的程序使用说明,谢谢!
呵呵,只是表示一下感激之情,还有你的热情:) 绝对没有别的意思!kingzai() :
我也试过这个例子,可是我调试的时候确跳不到MyExtTextOutW函数中,而用softice加断点则能够在有程序调用ExtTextOutW时跳出:(
请指点!
真不好意思,我没做过打印:(
我认为理论上是这样的,等我试试先:)
你可以参考,对你有用:
http://www.codeproject.com/useritems/syswidehook9x.asp
http://www.codeproject.com/system/hooksys.asp
http://www.csdn.net/develop/Read_Article.asp?Id=15119
要hook其他进程,注入dll是必须的了..那么该采用哪种方法呢???
是全局hook 还是 远程线程呢...
就像上面的那篇文章..
是用全局hook 动态连接库作的dll.但在win2k中,我还是无法hook其他进程..
那么到底是什么原因呢????