创建同explorer相同用户的进程,有什么作用呢?
有这样一种情况,如果你的进程是以系统服务启动的并要进行屏幕获取工作,你可以试试看,能不能把屏幕获取下来.呵呵..有一种办法就是创建一个和explorer相同用户的子进程
其中的一种方法:
//
szProcPath 为进程的路径
BOOL CMainFun::StartExplorerProc( char * szProcPath)
... {
// Typedefs for function pointers in USERENV.DLL
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
HANDLE hToken,
LPPROFILEINFO lpProfileInfo
);
HMODULE hLib = LoadLibrary( _T("userenv.dll") );
LPFNLOADUSERPROFILE LoadUserProfile = NULL;
#ifdef UNICODE
LoadUserProfile =
(LPFNLOADUSERPROFILE) GetProcAddress( hLib,
"LoadUserProfileW" );
#else
LoadUserProfile =
(LPFNLOADUSERPROFILE) GetProcAddress( hLib,
"LoadUserProfileA" );
#endif
if (!LoadUserProfile) ...{
return FALSE;
}
//改变进程令牌
HANDLE hExistToken;
HANDLE hNewToken;
HANDLE hProcessSnap = NULL;
HANDLE hProcess = NULL;
BOOL bFound = FALSE;
DWORD dwPid;
PROCESSENTRY32 pe32 = ...{0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, "explorer.exe") == 0)
...{
dwPid = pe32.th32ProcessID;
bFound = TRUE;
break;
}
}
// 没有找到explorer.exe
if (!bFound)
...{
return FALSE;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
if(hProcess != NULL)
...{
if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hExistToken))
...{
// 复制句柄
if(DuplicateTokenEx(hExistToken,TOKEN_ALL_ACCESS,NULL,SecurityDelegation,
TokenPrimary,&hNewToken));
}
}
STARTUPINFO lp = ...{0};
lp.cb = sizeof(lp);
PROCESS_INFORMATION pi ;
lp.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
lp.wShowWindow = SW_HIDE;
PROFILEINFO profile=...{0};
profile.dwSize = sizeof(PROFILEINFO);
profile.lpUserName = "administrator";
if (LoadUserProfile(hNewToken,&profile) == NULL)
...{
return FALSE;
}
BOOL bRet = CreateProcessAsUser(hNewToken
,NULL
,szProcPath
,NULL
,NULL
,FALSE
,CREATE_NO_WINDOW
,NULL
,NULL
,&lp
,&pi
);
return bRet;
}
BOOL CMainFun::StartExplorerProc( char * szProcPath)
... {
// Typedefs for function pointers in USERENV.DLL
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
HANDLE hToken,
LPPROFILEINFO lpProfileInfo
);
HMODULE hLib = LoadLibrary( _T("userenv.dll") );
LPFNLOADUSERPROFILE LoadUserProfile = NULL;
#ifdef UNICODE
LoadUserProfile =
(LPFNLOADUSERPROFILE) GetProcAddress( hLib,
"LoadUserProfileW" );
#else
LoadUserProfile =
(LPFNLOADUSERPROFILE) GetProcAddress( hLib,
"LoadUserProfileA" );
#endif
if (!LoadUserProfile) ...{
return FALSE;
}
//改变进程令牌
HANDLE hExistToken;
HANDLE hNewToken;
HANDLE hProcessSnap = NULL;
HANDLE hProcess = NULL;
BOOL bFound = FALSE;
DWORD dwPid;
PROCESSENTRY32 pe32 = ...{0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, "explorer.exe") == 0)
...{
dwPid = pe32.th32ProcessID;
bFound = TRUE;
break;
}
}
// 没有找到explorer.exe
if (!bFound)
...{
return FALSE;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
if(hProcess != NULL)
...{
if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hExistToken))
...{
// 复制句柄
if(DuplicateTokenEx(hExistToken,TOKEN_ALL_ACCESS,NULL,SecurityDelegation,
TokenPrimary,&hNewToken));
}
}
STARTUPINFO lp = ...{0};
lp.cb = sizeof(lp);
PROCESS_INFORMATION pi ;
lp.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
lp.wShowWindow = SW_HIDE;
PROFILEINFO profile=...{0};
profile.dwSize = sizeof(PROFILEINFO);
profile.lpUserName = "administrator";
if (LoadUserProfile(hNewToken,&profile) == NULL)
...{
return FALSE;
}
BOOL bRet = CreateProcessAsUser(hNewToken
,NULL
,szProcPath
,NULL
,NULL
,FALSE
,CREATE_NO_WINDOW
,NULL
,NULL
,&lp
,&pi
);
return bRet;
}
第二种:
注入到explorer里面,在explorer里面创建一个进程
#include
"
windows.h
"
#include " tlhelp32.h "
// lpCmdLine 开始4个字节是 WinExec的地址,后面是WinExec的第一个参数
__declspec(naked) void WinExecT(
LPCSTR lpCmdLine // address of command line
)
... {
//24个字节
__asm
...{
push ebp;
mov ebp,esp;
add esp,-8; //两个参数
mov ebx,lpCmdLine;
mov eax,[ebx];
push 0; //SW_HIDE
add ebx,4;
push ebx;
call eax;
add esp,8;
pop ebp;
ret;
}
}
BOOL EnableDebugPrivNT(VOID)
... {
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;
// Retrieve a handle of the access token
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) ...{
return FALSE;
}
// Enable the SE_DEBUG_NAME privilege
LookupPrivilegeValue((LPSTR) NULL,SE_DEBUG_NAME,&DebugValue);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL))...{
return FALSE;
}
// The return value of AdjustTokenPrivileges can't be tested
if (GetLastError() != ERROR_SUCCESS) ...{
return FALSE;
}
return TRUE;
}
// 获得 explorer.exe 的ID
DWORD GetExplorerID()
... {
BOOL bFound = FALSE;
PROCESSENTRY32 pe32 = ...{0};
char szProcessName[MAX_PATH] = "explorer.exe";
HANDLE hProcessSnap = NULL;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(!bFound && Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, szProcessName) == 0)
bFound = TRUE;
}
CloseHandle(hProcessSnap);
if(!bFound)
...{
//SendData(&bRet,sizeof(bRet),emKillprocess);
return -1;
}
return pe32.th32ProcessID;
}
HANDLE CreateRT(DWORD dwPid, LPCTSTR lpCmdLine)
... {
HANDLE hRemoteProcess = NULL;
EnableDebugPrivNT();
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
//得到 WinExec 的地址
DWORD xx = (DWORD)GetProcAddress(GetModuleHandle("Kernel32"),"WinExec");
char buf[MAX_PATH+4]; //WinExec 的地址需要4个字节
memcpy(buf,(char *)&xx,4);
strcpy(buf+4,lpCmdLine);
DWORD dwSize = (1 + lstrlenA(lpCmdLine)) * sizeof(char)+4;
char *pszCmdLineRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL,
dwSize, MEM_COMMIT, PAGE_READWRITE);
//参数写入
WriteProcessMemory(hRemoteProcess, pszCmdLineRemote,
(PVOID) buf, dwSize, NULL);
//多写入几个字节也无所谓
//这里一定要注意
//在debug版本下面call WinexecT是先 call 到一个 jmp 17的地方,然后由这个地方调用
//WinExecT,但是在realese版本下面就是直接call 的WinExecT的地址了
/**//*
//debug版本下面使用
DWORD tt = (DWORD)WinExecT;
DWORD yy = (DWORD)(*((char *)WinExecT +1));
tt+=yy+5;*/
dwSize = 32;
char *pszWinExecRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL,
dwSize, MEM_COMMIT, PAGE_READWRITE);
//函数写入
WriteProcessMemory(hRemoteProcess, pszWinExecRemote,
(PVOID) WinExecT, dwSize, NULL);
PTHREAD_START_ROUTINE pfnStartAddr =
(PTHREAD_START_ROUTINE)pszWinExecRemote;
return CreateRemoteThread( hRemoteProcess, NULL,0,
pfnStartAddr, pszCmdLineRemote, 0, NULL);
}
int main()
... {
DWORD pid = GetExplorerID();
if (pid == -1) ...{
return 0;
}
char buf[MAX_PATH]=...{0};
GetSystemDirectory(buf,MAX_PATH);
// 创建的子进程为%systemroot%/test.exe
strcat(buf,"test.exe");
CreateRT(pid,buf);
return 0;
}
#include " tlhelp32.h "
// lpCmdLine 开始4个字节是 WinExec的地址,后面是WinExec的第一个参数
__declspec(naked) void WinExecT(
LPCSTR lpCmdLine // address of command line
)
... {
//24个字节
__asm
...{
push ebp;
mov ebp,esp;
add esp,-8; //两个参数
mov ebx,lpCmdLine;
mov eax,[ebx];
push 0; //SW_HIDE
add ebx,4;
push ebx;
call eax;
add esp,8;
pop ebp;
ret;
}
}
BOOL EnableDebugPrivNT(VOID)
... {
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;
// Retrieve a handle of the access token
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) ...{
return FALSE;
}
// Enable the SE_DEBUG_NAME privilege
LookupPrivilegeValue((LPSTR) NULL,SE_DEBUG_NAME,&DebugValue);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL))...{
return FALSE;
}
// The return value of AdjustTokenPrivileges can't be tested
if (GetLastError() != ERROR_SUCCESS) ...{
return FALSE;
}
return TRUE;
}
// 获得 explorer.exe 的ID
DWORD GetExplorerID()
... {
BOOL bFound = FALSE;
PROCESSENTRY32 pe32 = ...{0};
char szProcessName[MAX_PATH] = "explorer.exe";
HANDLE hProcessSnap = NULL;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(!bFound && Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, szProcessName) == 0)
bFound = TRUE;
}
CloseHandle(hProcessSnap);
if(!bFound)
...{
//SendData(&bRet,sizeof(bRet),emKillprocess);
return -1;
}
return pe32.th32ProcessID;
}
HANDLE CreateRT(DWORD dwPid, LPCTSTR lpCmdLine)
... {
HANDLE hRemoteProcess = NULL;
EnableDebugPrivNT();
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
//得到 WinExec 的地址
DWORD xx = (DWORD)GetProcAddress(GetModuleHandle("Kernel32"),"WinExec");
char buf[MAX_PATH+4]; //WinExec 的地址需要4个字节
memcpy(buf,(char *)&xx,4);
strcpy(buf+4,lpCmdLine);
DWORD dwSize = (1 + lstrlenA(lpCmdLine)) * sizeof(char)+4;
char *pszCmdLineRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL,
dwSize, MEM_COMMIT, PAGE_READWRITE);
//参数写入
WriteProcessMemory(hRemoteProcess, pszCmdLineRemote,
(PVOID) buf, dwSize, NULL);
//多写入几个字节也无所谓
//这里一定要注意
//在debug版本下面call WinexecT是先 call 到一个 jmp 17的地方,然后由这个地方调用
//WinExecT,但是在realese版本下面就是直接call 的WinExecT的地址了
/**//*
//debug版本下面使用
DWORD tt = (DWORD)WinExecT;
DWORD yy = (DWORD)(*((char *)WinExecT +1));
tt+=yy+5;*/
dwSize = 32;
char *pszWinExecRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL,
dwSize, MEM_COMMIT, PAGE_READWRITE);
//函数写入
WriteProcessMemory(hRemoteProcess, pszWinExecRemote,
(PVOID) WinExecT, dwSize, NULL);
PTHREAD_START_ROUTINE pfnStartAddr =
(PTHREAD_START_ROUTINE)pszWinExecRemote;
return CreateRemoteThread( hRemoteProcess, NULL,0,
pfnStartAddr, pszCmdLineRemote, 0, NULL);
}
int main()
... {
DWORD pid = GetExplorerID();
if (pid == -1) ...{
return 0;
}
char buf[MAX_PATH]=...{0};
GetSystemDirectory(buf,MAX_PATH);
// 创建的子进程为%systemroot%/test.exe
strcat(buf,"test.exe");
CreateRT(pid,buf);
return 0;
}
第三种方法:
进程创建的时候会调用NTDLL.dll中的NtCreateProcess或者NtCreateProcessEx,而NtCreateProcess或者NtCreateProcessEx的参数ParentProcess表示父进程的句柄,因此我们可以hook NtCreateProcess或者NtCreateProcessEx函数,改变其父进程句柄,从而改变创建的进程的用户名,具体代码如下:
#include
"
windows.h
"
#include " stdio.h "
#include " TCHAR.h "
#include " tlhelp32.h "
#pragma pack(1)
// 定义跳转的结构
typedef struct
... {
BYTE mov_eax;
LPVOID address;
WORD jump_eax;
} ASMJUMP, * PASMJUMP;
// 父进程句柄
HANDLE hParentProc;
// Haked NtCreateProcess
void __declspec(naked)HackedNtCreateProcess()
... {
_asm
...{
/**//*
NtCreateProcess 的定义如下
NTSYSAPI
NTSTATUS
NTAPI
NtCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL
);
ParentProcess 便是父进程的句柄,我们将它改变为explorer的进程句柄
*/
mov eax,hParentProc;
// [esp+16]便是 ParentProcess
mov dword ptr [esp+16],eax;
// 留下填充的字节数
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
}
}
BOOL EnableDebugPrivNT(VOID)
... {
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) ...{
return FALSE;
}
LookupPrivilegeValue((LPSTR) NULL,SE_DEBUG_NAME,&DebugValue);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL))...{
return FALSE;
}
if (GetLastError() != ERROR_SUCCESS) ...{
return FALSE;
}
return TRUE;
}
// 获得 explorer.exe 的ID
DWORD GetExplorerID()
... {
BOOL bFound = FALSE;
PROCESSENTRY32 pe32 = ...{0};
char szProcessName[MAX_PATH] = "explorer.exe";
HANDLE hProcessSnap = NULL;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(!bFound && Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, szProcessName) == 0)
bFound = TRUE;
}
CloseHandle(hProcessSnap);
if(!bFound)
...{
return -1;
}
return pe32.th32ProcessID;
}
int main()
... {
DWORD pid = GetExplorerID();
if (pid == -1) ...{
return 0;
}
HANDLE hRemoteProcess = NULL;
EnableDebugPrivNT();
hParentProc = OpenProcess(PROCESS_CREATE_PROCESS,TRUE,pid);
if (!hParentProc)
...{
return -1;
}
PASMJUMP NtCreateProcessHook = NULL;
//获取版本信息
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
BOOL Found = FALSE;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
...{
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return -1;
}
//
if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) ...{
return -1;
}
if ( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
...{
// Microsoft Windows NT 4.0
return -1;
}
else if ( osvi.dwMajorVersion == 5 &&
osvi.dwMinorVersion == 0 )
...{
// Microsoft Windows 2000
printf("%d--%d--%d ",osvi.dwBuildNumber,osvi.wServicePackMajor,osvi.wServicePackMinor);
NtCreateProcessHook = (PASMJUMP)
GetProcAddress(
GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateProcess");
if (NtCreateProcessHook==NULL)
...{
return -1;
}
}
else if ( osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion == 1 || osvi.dwMinorVersion == 2) )
...{
// windows xp or 2003
printf("%d--%d--%d ",osvi.dwBuildNumber,osvi.wServicePackMajor,osvi.wServicePackMinor);
NtCreateProcessHook = (PASMJUMP)
GetProcAddress(
GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateProcessEx");
if (NtCreateProcessHook==NULL)
...{
return -1;
}
}
// 改变被hook的函数地址的内存属性,使其可写
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(NtCreateProcessHook,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
DWORD dw;
VirtualProtect(mbi.AllocationBase,mbi.RegionSize,
PAGE_EXECUTE_READWRITE,&dw);
// 改变我们自己函数的属性
VirtualQuery(HackedNtCreateProcess,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.AllocationBase,mbi.RegionSize,
PAGE_EXECUTE_READWRITE,&dw);
for (int i=0;i<23;i++)
...{
// 把NtCreateProcess或者NtCreateProcessEx的23个字节复制到我们的函数中
*((char *)HackedNtCreateProcess+10+i) = *((char *)NtCreateProcessHook+i);
}
// 填充结构,填充后被hook的函数变成如下形式
// mov eax,HackedNtCreateProcess
// jmp eax
// 因此当系统调用NtCreateProcess或者NtCreateProcessEx
// 进行进程创建的时候,会跳转到 HackedNtCreateProcess中执行
NtCreateProcessHook->mov_eax = 0xB8;
NtCreateProcessHook->address = HackedNtCreateProcess;
NtCreateProcessHook->jump_eax = 0xE0FF;
// 准备调用createprocess创建进程
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&pi,sizeof (PROCESS_INFORMATION));
ZeroMemory(&si,sizeof (STARTUPINFO));
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.cb = sizeof(STARTUPINFO);
char buf[MAX_PATH]=...{0};
// 启动计算器
GetSystemDirectory(buf,MAX_PATH);
strcat(buf,"/calc.exe");
if (!CreateProcess(NULL,buf,
NULL, NULL,
FALSE,
0,NULL,NULL,
&si,
&pi))
...{
return -1;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
#include " stdio.h "
#include " TCHAR.h "
#include " tlhelp32.h "
#pragma pack(1)
// 定义跳转的结构
typedef struct
... {
BYTE mov_eax;
LPVOID address;
WORD jump_eax;
} ASMJUMP, * PASMJUMP;
// 父进程句柄
HANDLE hParentProc;
// Haked NtCreateProcess
void __declspec(naked)HackedNtCreateProcess()
... {
_asm
...{
/**//*
NtCreateProcess 的定义如下
NTSYSAPI
NTSTATUS
NTAPI
NtCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL
);
ParentProcess 便是父进程的句柄,我们将它改变为explorer的进程句柄
*/
mov eax,hParentProc;
// [esp+16]便是 ParentProcess
mov dword ptr [esp+16],eax;
// 留下填充的字节数
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
}
}
BOOL EnableDebugPrivNT(VOID)
... {
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) ...{
return FALSE;
}
LookupPrivilegeValue((LPSTR) NULL,SE_DEBUG_NAME,&DebugValue);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL))...{
return FALSE;
}
if (GetLastError() != ERROR_SUCCESS) ...{
return FALSE;
}
return TRUE;
}
// 获得 explorer.exe 的ID
DWORD GetExplorerID()
... {
BOOL bFound = FALSE;
PROCESSENTRY32 pe32 = ...{0};
char szProcessName[MAX_PATH] = "explorer.exe";
HANDLE hProcessSnap = NULL;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe32.dwSize = sizeof(PROCESSENTRY32);
while(!bFound && Process32Next(hProcessSnap, &pe32))
...{
if(lstrcmpi(pe32.szExeFile, szProcessName) == 0)
bFound = TRUE;
}
CloseHandle(hProcessSnap);
if(!bFound)
...{
return -1;
}
return pe32.th32ProcessID;
}
int main()
... {
DWORD pid = GetExplorerID();
if (pid == -1) ...{
return 0;
}
HANDLE hRemoteProcess = NULL;
EnableDebugPrivNT();
hParentProc = OpenProcess(PROCESS_CREATE_PROCESS,TRUE,pid);
if (!hParentProc)
...{
return -1;
}
PASMJUMP NtCreateProcessHook = NULL;
//获取版本信息
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
BOOL Found = FALSE;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
...{
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return -1;
}
//
if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) ...{
return -1;
}
if ( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
...{
// Microsoft Windows NT 4.0
return -1;
}
else if ( osvi.dwMajorVersion == 5 &&
osvi.dwMinorVersion == 0 )
...{
// Microsoft Windows 2000
printf("%d--%d--%d ",osvi.dwBuildNumber,osvi.wServicePackMajor,osvi.wServicePackMinor);
NtCreateProcessHook = (PASMJUMP)
GetProcAddress(
GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateProcess");
if (NtCreateProcessHook==NULL)
...{
return -1;
}
}
else if ( osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion == 1 || osvi.dwMinorVersion == 2) )
...{
// windows xp or 2003
printf("%d--%d--%d ",osvi.dwBuildNumber,osvi.wServicePackMajor,osvi.wServicePackMinor);
NtCreateProcessHook = (PASMJUMP)
GetProcAddress(
GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateProcessEx");
if (NtCreateProcessHook==NULL)
...{
return -1;
}
}
// 改变被hook的函数地址的内存属性,使其可写
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(NtCreateProcessHook,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
DWORD dw;
VirtualProtect(mbi.AllocationBase,mbi.RegionSize,
PAGE_EXECUTE_READWRITE,&dw);
// 改变我们自己函数的属性
VirtualQuery(HackedNtCreateProcess,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.AllocationBase,mbi.RegionSize,
PAGE_EXECUTE_READWRITE,&dw);
for (int i=0;i<23;i++)
...{
// 把NtCreateProcess或者NtCreateProcessEx的23个字节复制到我们的函数中
*((char *)HackedNtCreateProcess+10+i) = *((char *)NtCreateProcessHook+i);
}
// 填充结构,填充后被hook的函数变成如下形式
// mov eax,HackedNtCreateProcess
// jmp eax
// 因此当系统调用NtCreateProcess或者NtCreateProcessEx
// 进行进程创建的时候,会跳转到 HackedNtCreateProcess中执行
NtCreateProcessHook->mov_eax = 0xB8;
NtCreateProcessHook->address = HackedNtCreateProcess;
NtCreateProcessHook->jump_eax = 0xE0FF;
// 准备调用createprocess创建进程
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&pi,sizeof (PROCESS_INFORMATION));
ZeroMemory(&si,sizeof (STARTUPINFO));
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.cb = sizeof(STARTUPINFO);
char buf[MAX_PATH]=...{0};
// 启动计算器
GetSystemDirectory(buf,MAX_PATH);
strcat(buf,"/calc.exe");
if (!CreateProcess(NULL,buf,
NULL, NULL,
FALSE,
0,NULL,NULL,
&si,
&pi))
...{
return -1;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}