In fact, there are a lot of articles on ssdt restoration on the Internet, which seems to be very simple. To use a netizen, It is the technology that Cai B uses. However, I have actually spent some time, and it may be that my understanding is poor. It's really easy to get it out after two or three days, but some articles are vague.
The following are some important points:
1. ssdt already exists in the original pe file. (Ntoskrnl.exe%ntkrnlpa.exe%ntkrnlmp.exe%ntkrpamp.exe)
The operating system selects the appropriate system based on whether it is a multi-processor platform and whether it supports PAE (Physical Address Extension ).
Picasa Content
System File.
Ntoskrnl.exe
A single x86 processor uses a physical memory of no more than 4 GB.
Ntkrnlpa.exe
Single x86 processor, supporting PAE.
Ntkrnlmp.exe
Multi-processor, with no more than 4 GB physical memory.
Ntkrpamp.exe
Multi-processor, supporting PAE.
// If it is determined that the system kernel is ntoskrnl.exeand ntkrnlpa.exe? Multi-core int nPaeOpen = 0; WCHAR * kernelName = NULL ;__ asm {_ emit 0x0f _ emit 0x20 _ emit 0xe0 mov edx, 0x1 shl edx, 5 and eax, edx shr eax, 5 mov nPaeOpen, eax} kernelName = nPaeOpen? L "ntoskrnl.exe": L "ntkrnlpa ";
2. Location calculation involves several addresses:
A. The existing ssdt address can be demonstrated through windbg. (The Address Table is stored in 0x80504960)
B. Locate the current kernel base address (804d8000)
In this case, ntkrpamp.exe is used. I found some information:
C. With these two addresses, you can calculate RVA = 0x80504960-0x804d8000 = 0x2C960
D.we can go to ntkrnlpa.exe to find the corresponding File offset (2BF60)
E. Use UE to find the actual value (04 C1 4C 00, that is, 0x004CC104)
F. Get it done. Finally, verify that 0x004CC104-ImageBase + kernel base address
0x004CC104-0x00400000 + 0x804d8000 = 805A4104
In windbg, check that the address is correct. If the address does not match, it must have been hooked up.
Post point implementation code:
// Obtain the SSDT table void GetSSDTFromPE (const SSDT_PARAM & ssdt_param) {gvSSDTList in the original PE File Based on RVA. clear (); const DWORD rva = ssdt_param.ServiceTableBase-ssdt_param.nKernelImageBase; HANDLE hMapFile = NULL; HANDLE hFile = NULL; SIZE_T size = 0; int ECode = 0; PVOID pLoadBase = NULL; _ try {hFile = CreateFile (ssdt_param.kernelpath, FILE_ALL_ACCESS, file_pai_read | file_pai_write, NULL, OPEN_EXISTING, FILE_AT TRIBUTE_NORMAL, NULL); if (hFile = INVALID_HANDLE_VALUE) {DisplayError (_ T ("CreateFile"), GetLastError (); RaiseException (1, // throw? Outbound? Abnormal? Regular? Code? Is it?? SEH differences? Regular? 0, 0, NULL); // No? Yes? Parameter? Number? _ Leave;} DWORD dwBytesInBlock = GetFileSize (hFile, NULL); // text?? Long? Degree? HMapFile = CreateFileMapping (hFile, // use paging file NULL, // default security PAGE_READWRITE, 0, // max. object size dwBytesInBlock, // buffer size NULL); // name of mapping object CloseHandle (hFile); if (hMapFile = NULL) {RaiseException (2, 0, 0, 0, NULL); _ leave;} pLoadBase = MapViewOfFile (hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, dwBytesInBlock); if (pLoadBase = NULL) {RaiseException (3, 0, 0, NULL ); _ leave;} // _ tprintf (_ T ("ImageBase = 0x % x \ n"), pLoadBase); PIMAGE_NT_HEADERS pImageNtHeader = ImageNtHeader (pLoadBase ); if (pImageNtHeader = NULL) {RaiseException (3, 0, 0, NULL); _ leave;} DWORD ImageBase = pImageNtHeader-> OptionalHeader. imageBase; DWORD * VaAddr = (DWORD *) ImageRvaToVa (pImageNtHeader, pLoadBase, rva, NULL); if (VaAddr = NULL) {RaiseException (4, 0, 0, NULL ); _ leave;} // _ tprintf (_ T ("Index \ tAddress \ n"); for (DWORD I = 1; I <= ssdt_param.nCount; ++ I, ++ VaAddr) {// _ tprintf (TEXT ("0x % x \ t [0x % x] \ n"), I, * VaAddr-ImageBase + ssdt_param.nKernelImageBase); gvSSDTList. push_back (* VaAddr-ImageBase + ssdt_param.nKernelImageBase);} _ encode T (ECode = GetExceptionCode () {DisplayError (_ T (""), GetLastError ());}} _ finally {if (pLoadBase) UnmapViewOfFile (pLoadBase); if (hMapFile) CloseHandle (hMapFile); if (hFile) CloseHandle (hFile) ;}return ;}