这段代码在VS2008 Win7下编译
Release 下通过
Debug下到WaitForSingleObject 有异常
0xC0000005: Access violation
本人新手+菜鸟
苦苦baidu&google半夜未果
求高手解答
Thanks in advance.
PS:
代码非本人写的
来自这里
http://win32.mvps.org/processes/remthread.html
// demonstrates getting the command line of another process
// requires PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION,
// PROCESS_VM_WRITE, PROCESS_VM_READ to the target, or the
// SeDebugPrivilege
// *** You *must* remove "/GZ" from the debug build settings ***
// (If you use my (felixk's) project file, this has already happened)
#include "stdafx.h"
#define lenof(x) ( sizeof (x) / sizeof ((x)[0]) )
typedef const wchar_t *(__stdcall *tGCLW)( void );
const DWORD MAXINJECTSIZE = 4096;
struct Common
{
DWORD gle; // last error from remote thread
tGCLW pGCLW; // address of GetCommandLineW()
wchar_t str[2000]; // the command line buffer
};
// try to enable SeDebugPrivilege
void EnableDebugPriv( void );
// inject function bem() into target process
bool Bugger( HANDLE h, wstring &str );
// and this is the code we are injecting
DWORD __stdcall bem( Common *c );
int wmain( int argc, wchar_t *argv[] )
{
int i;
DWORD pid;
HANDLE h;
wstring str;
if ( argc == 1 )
{
wcout << endl << L"usage: remthread pid [pid ...]" << endl;
wcout << L"Reports the command lines of the specified processes." << endl;
wcout << L"Use \"-1\" to have the program look at itself." << endl;
return 1;
}
EnableDebugPriv();
for ( i = 1; i < argc; ++ i )
{
wstringstream( argv[i] ) >> pid;
if ( pid == (DWORD) -1 )
pid = GetCurrentProcessId();
wcout << L"pid " << pid << L": ";
h = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid );
if ( h != 0 )
{
if ( Bugger( h, str ) )
wcout << endl << L" \"" << str.c_str() << L"\"";
CloseHandle( h );
wcout << endl;
}
else
wcout << L"open failed, gle = " << GetLastError() << endl;
}
return 0;
}
void EnableDebugPriv( void )
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if ( ! OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
wcout << L"OPT() failed, gle = " << GetLastError() <<
L" SeDebugPrivilege is not available." << endl;
return;
}
if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
{
wcout << L"LPV() failed, gle = " << GetLastError() <<
L" SeDebugPrivilege is not available." << endl;
CloseHandle( hToken );
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
wcout << L"ATP() failed, gle = " << GetLastError() <<
L" SeDebugPrivilege is not available." << endl;
CloseHandle( hToken );
}
bool Bugger( HANDLE h, wstring &str )
{
HANDLE ht = 0;
void *p = 0;
Common *c = 0;
bool result = false;
DWORD rc;
HMODULE hk32 = 0;
Common localCopy;
// allocate memory
p = VirtualAllocEx( h, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if ( p == 0 )
{
wcout << L"VAE() failed, gle = " << GetLastError();
goto cleanup;
}
c = (Common *) VirtualAllocEx( h, 0, sizeof Common, MEM_COMMIT, PAGE_READWRITE );
if ( c == 0 )
{
wcout << L"VAE() failed, gle = " << GetLastError();
goto cleanup;
}
// copy function there
if ( ! WriteProcessMemory( h, p, &bem, MAXINJECTSIZE, 0 ) )
{
wcout << L"WPM() failed, gle = " << GetLastError();
goto cleanup;
}
// initialize data area for remote guy
hk32 = LoadLibrary( L"kernel32.dll" );
if ( hk32 == 0 )
{
wcout << L"LL() failed, gle = " << GetLastError();
goto cleanup;
}
localCopy.gle = 0;
localCopy.pGCLW = (tGCLW) GetProcAddress( hk32, "GetCommandLineW" );
if ( localCopy.pGCLW == 0 )
{
wcout << L"GPA() failed, gle = " << GetLastError();
goto cleanup;
}
FreeLibrary( hk32 );
hk32 = 0;
localCopy.str[0] = L'\0';
if ( ! WriteProcessMemory( h, c, &localCopy, sizeof localCopy, 0 ) )
{
wcout << L"WPM() failed, gle = " << GetLastError();
goto cleanup;
}
// CreateRemoteThread()
ht = CreateRemoteThread( h, 0, 0, (DWORD (__stdcall *)( void *)) p, c, 0, &rc );
if ( ht == NULL )
{
wcout << L"CRT() failed, gle = " << GetLastError();
goto cleanup;
}
rc = WaitForSingleObject( ht, 3000 );
switch ( rc )
{
case WAIT_TIMEOUT:
wcout << L"WFSO() timed out. Odd!";
goto cleanup;
case WAIT_FAILED:
wcout << L"WFSO() failed, gle = " << GetLastError();
goto cleanup;
case WAIT_OBJECT_0:
// this might just have worked, pick up the result!
if ( ! ReadProcessMemory( h, c, &localCopy, sizeof localCopy, 0 ) )
{
wcout << L"RPM() failed, gle = " << GetLastError();
goto cleanup;
}
if ( localCopy.gle == 0 )
{
str = localCopy.str;
result = true;
wcout << L"successfully buggered.";
}
else
wcout << L"Remote thread failed, gle = " << localCopy.gle;
break;
default:
wcout << L"WFSO() returned a surprise! rc = " <<
rc << L", gle = " << GetLastError();
break;
}
cleanup:
CloseHandle( ht );
if ( p != 0 )
VirtualFreeEx( h, p, 0, MEM_RELEASE );
if ( c != 0 )
VirtualFreeEx( h, c, 0, MEM_RELEASE );
if ( hk32 != 0 )
FreeLibrary( hk32 );
return result;
}
// The whole shebang makes a number of assumptions:
// -- target process is a Win32 process
// -- kernel32.dll loaded at same address in each process (safe)
// -- bem() shorter than MAXINJECTSIZE
// -- bem() does not rely on the C/C++ runtime
// -- /GZ is _not_ used. (If it is, the compiler generates calls
// to functions which are not injected into the target. Oops!
DWORD __stdcall bem( Common *c )
{
const wchar_t *src;
wchar_t *tgt, *end;
// __asm int 3;
src = c->pGCLW();
tgt = &c->str[0];
end = &c->str[lenof( c->str ) - 1];
if ( src == 0 || tgt == 0 || end == 0 )
{
c->gle = 998;
return 0;
}
for ( ; *src != L'\0' && tgt < end; ++ src, ++ tgt )
*tgt = *src;
*tgt = L'\0';
c->gle = 0;
return 0;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)