前些天写了个shellcode注入进程。发现在自己机器上到可以跑。换到win7上却找不到kernelbase了加载user32也就失败。原来程序为:
pushad
push ebp
mov ebp, esp
// ebp-0x04 ====> hmodkern32
// ebp-0x08 ====> dwAddrOfGetProcAddress
// ebp-0x0C ====> dwAddrOfLoadLibrary
// ebp-0x10 ====> hmoduser32
// ebp-0x14 ====> dwAddrOfMessageBoxA
sub esp, 0x14
//hmodkern32 = _GetBaseKernel32();
call _GetBaseKernel32
mov [ebp - 0x04], eax // save Base Address of "Kernel32.dll"
//dwAddrOfGetProcAddress = _GetGetProcAddrBase(hmodkern32);
push eax
call _GetGetProcAddrBase
mov [ebp - 0x08], eax // save GetProcAddress
add esp, 0x04
//load user32.dll
// dwAddrOfLoadLibrary = GetProcAddress(hmodkern32, "LoadLibrary")
call _get_loadlibrary
_emit 'L'
_emit 'o'
_emit 'a'
_emit 'd'
_emit 'L'
_emit 'i'
_emit 'b'
_emit 'r'
_emit 'a'
_emit 'r'
_emit 'y'
_emit 'A'
_emit 0x0
_get_loadlibrary:
push [ebp - 0x04]
call dword ptr [ebp - 0x08]
mov [ebp - 0x0C], eax
// hmoduser32 = LoadLibraryA("user32.dll");
call _load_user32
_emit 'u'
_emit 's'
_emit 'e'
_emit 'r'
_emit '3'
_emit '2'
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0x0
_load_user32:
call dword ptr [ebp - 0x0C]
mov [ebp-0x10], eax
//GET KERBASE SOURCE CODE
_GetBaseKernel32:
push ebp
mov ebp, esp
push esi
push edi
mov eax, fs:[0x30]
mov eax, [eax + 0x0c]
mov esi, [eax + 0x1c]
mov eax, [esi]
mov edi, [eax + 0x08]
mov eax, edi // eax = BaseAddress of "kernel32.dll"
pop edi
pop esi
mov esp, ebp
pop ebp
ret
// ---------------------------------------------------------
// type : DWORD GetGetProcAddrBase(DWORD base)
_GetGetProcAddrBase:
push ebp
mov ebp, esp
push edx
push edi
push esi
mov ebx, [ebp+8]
mov eax, [ebx + 0x3c] // edi = BaseAddr, eax = pNtHeader
mov edx, [ebx + eax + 0x78]
add edx, ebx // edx = Export Table (RVA)
mov ecx, [edx + 0x18] // ecx = NumberOfNames
mov edi, [edx + 0x20] //
add edi, ebx // ebx = AddressOfNames
找了半天 终于找到个好的办法和大家share下。(高手飘过)
int main( void )
{
OSVERSIONINFOEX VersionInfoEx = { 0 };
DWORD dwBaseAddressA = 0;
DWORD dwBaseAddressB = 0;
DWORD dwBaseAddressC = 0;
DWORD dwBaseAddressD = 0;
VersionInfoEx.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
GetVersionEx( (LPOSVERSIONINFO)&VersionInfoEx );
if( VersionInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT )
printf( "Warning: Not an NT based platform, YMMV!\n" );
printf( "-------------------------------------------------------------\n" );
printf( "Microsoft Windows [Version %d.%d.%d] %s\n", VersionInfoEx.dwMajorVersion, VersionInfoEx.dwMinorVersion, VersionInfoEx.dwBuildNumber, VersionInfoEx.szCSDVersion );
printf( "-------------------------------------------------------------\n" );
printf( "GetModuleHandleA( \"kernelbase.dll\" ) = 0x%08X\n", (DWORD)GetModuleHandleA( "kernelbase.dll" ) );
printf( "GetModuleHandleA( \"kernel32.dll\" ) = 0x%08X\n", (DWORD)GetModuleHandleA( "kernel32.dll" ) );
printf( "GetModuleHandleA( \"ntdll.dll\" ) = 0x%08X\n", (DWORD)GetModuleHandleA( "ntdll.dll" ) );
printf( "-------------------------------------------------------------\n" );
// Get the actual kernel32 base address...
dwBaseAddressA = (DWORD)GetModuleHandleA( "kernel32.dll" );
// Try the first method...
__asm
{
xor ebx, ebx ; // clear ebx
mov ebx, fs:[ 0x30 ] ; // get a pointer to the PEB
mov ebx, [ ebx + 0x0C ] ; // get PEB->Ldr
mov ebx, [ ebx + 0x1C ] ; // get PEB->Ldr.InInitializationOrderModuleList.Flink (1st entry)
mov ebx, [ ebx ] ; // get the next entry (2nd entry)
mov ebx, [ ebx + 0x08 ] ; // get the 2nd entries base address (kernel32.dll)
mov dwBaseAddressB, ebx
}
printf( "Method 1: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressB, (dwBaseAddressA==dwBaseAddressB?"YES":"NO!") );
// Try the second method...
__asm
{
xor ebx, ebx ; // clear ebx
mov ebx, fs:[ 0x30 ] ; // get a pointer to the PEB
mov ebx, [ ebx + 0x0C ] ; // get PEB->Ldr
mov ebx, [ ebx + 0x14 ] ; // get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
mov ebx, [ ebx ] ; // get the next entry (2nd entry)
mov ebx, [ ebx ] ; // get the next entry (3rd entry)
mov ebx, [ ebx + 0x10 ] ; // get the 3rd entries base address (kernel32.dll)
mov dwBaseAddressC, ebx
}
printf( "Method 2: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressC, (dwBaseAddressA==dwBaseAddressC?"YES":"NO!") );
// Try the third method...
__asm
{
cld ; // clear the direction flag for the loop
xor edx, edx ; // zero edx
mov edx, fs:[ 0x30 ] ; // get a pointer to the PEB
mov edx, [ edx+0x0C ] ; // get PEB->Ldr
mov edx, [ edx+0x14 ] ; // get the first module from the InMemoryOrder module list
next_mod:
mov esi, [ edx+0x28 ] ; // get pointer to modules name (unicode string)
mov ecx, 24 ; // set ecx to this length for the loop
xor edi, edi ; // clear edi which will store the hash of the module name
loop_modname:
xor eax, eax ; // clear eax
lodsb ; // read in the next byte of the name
cmp al, 'a' ; // some versions of Windows use lower case module names
jl not_lowercase
sub al, 0x20 ; // if so normalise to uppercase
not_lowercase:
ror edi, 13 ; // rotate left our hash value
add edi, eax ; // add the next byte of the name
loop loop_modname ; // loop untill we have read enough
cmp edi, 0x6A4ABC5B ; // compare the hash with that of KERNEL32.DLL
mov ebx, [ edx+0x10 ] ; // get this modules base address
mov edx, [ edx ] ; // get the next module
jne next_mod ; // if it doesnt match, process the next module
mov dwBaseAddressD, ebx ; // when we get here EBX is the kernel32 base (or change to suit).
}
printf( "Method 3: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressD, (dwBaseAddressA==dwBaseAddressD?"YES":"NO!") );
printf( "-------------------------------------------------------------" );
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课