Created
December 22, 2022 06:12
-
-
Save iNoSec2/3f5cf95f4dbbce7f0d56d5fc943478d3 to your computer and use it in GitHub Desktop.
Windows API Hashing in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
namespace API_Hashing | |
{ | |
class Program | |
{ | |
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)] | |
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); | |
static void Main(string[] args) | |
{ | |
string processpath = @"C:\Windows\System32\calc.exe"; | |
long createprocessa_hash = 74176104191555; | |
STRUCTS.STARTUPINFO si = new STRUCTS.STARTUPINFO(); | |
STRUCTS.PROCESS_INFORMATION pi = new STRUCTS.PROCESS_INFORMATION(); | |
Console.WriteLine("[+] API Hash provided: {0}", createprocessa_hash); | |
IntPtr create_proca_address = GetfuncaddressbyHash("kernel32.dll", createprocessa_hash); | |
//Creating an instance of a CreateProcess delegate from our function pointer. | |
STRUCTS.CreateProcess CreateProcess = Marshal.GetDelegateForFunctionPointer(create_proca_address, typeof(STRUCTS.CreateProcess)) as STRUCTS.CreateProcess; | |
//Invoke CreateProcess using the delegate | |
bool success = CreateProcess(processpath, null, IntPtr.Zero, IntPtr.Zero, false, STRUCTS.ProcessCreationFlags.CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref si, out pi); | |
} | |
public static long Gethashfromstring(string inp) | |
{ | |
long sm = 0; | |
foreach (char c in inp) | |
{ | |
sm = sm * 10 + ((int)c % 10); | |
} | |
return sm; | |
} | |
public static IntPtr GetfuncaddressbyHash(string library, long hash) | |
{ | |
//Get base address of the module in which our exported function of interest resides (kernel32 in the case of OpenProcess) | |
IntPtr handle = LoadLibrary(library); | |
Console.WriteLine("[+] Library Base Address: 0x{0:X}", handle.ToString("X")); | |
//Obtain value of e_lfanew | |
STRUCTS.IMAGE_DOS_HEADER dosheader = (STRUCTS.IMAGE_DOS_HEADER)Marshal.PtrToStructure(handle, typeof(STRUCTS.IMAGE_DOS_HEADER)); | |
//Obtain signature | |
IntPtr sgn = IntPtr.Add(handle, (int)dosheader.e_lfanew); | |
STRUCTS.SIGNATURE sign = (STRUCTS.SIGNATURE)Marshal.PtrToStructure(sgn, typeof(STRUCTS.SIGNATURE)); | |
//Obtain PE file header | |
int si = 4 * sizeof(byte); | |
IntPtr file_head = IntPtr.Add(sgn, si); | |
STRUCTS.IMAGE_FILE_HEADER fileheader = (STRUCTS.IMAGE_FILE_HEADER)Marshal.PtrToStructure(file_head, typeof(STRUCTS.IMAGE_FILE_HEADER)); | |
//Obtain address of optional header | |
int ti; | |
unsafe | |
{ | |
ti = sizeof(STRUCTS.IMAGE_FILE_HEADER); | |
} | |
IntPtr opt_head = IntPtr.Add(file_head, ti); | |
Console.WriteLine("[+] Address of optional header: 0x{0:X}", opt_head.ToString("X")); | |
STRUCTS.IMAGE_OPTIONAL_HEADER64 optheader = (STRUCTS.IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure(opt_head, typeof(STRUCTS.IMAGE_OPTIONAL_HEADER64)); | |
IntPtr export_directory = IntPtr.Add(handle, (int)optheader.ExportTable.VirtualAddress); | |
Console.WriteLine("[+] Export table Address: 0x{0:X}", export_directory.ToString("X")); | |
//Obtain address of export directory | |
STRUCTS.IMAGE_EXPORT_DIRECTORY export_header = (STRUCTS.IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(export_directory, typeof(STRUCTS.IMAGE_EXPORT_DIRECTORY)); | |
Console.WriteLine("[+] RVA of Functions: 0x{0:X}", export_header.AddressOfFunctions); | |
Console.WriteLine("[+] RVA of Names: 0x{0:X}", export_header.AddressOfNames); | |
Console.WriteLine("[+] RVA of NameOrdinals: 0x{0:X}", export_header.AddressOfNameOrdinals); | |
int no_of_names = (int)export_header.NumberOfNames; | |
//int no_of_functions = (int)export_header.NumberOfFunctions; | |
//int base_val = (int)export_header.Base; | |
IntPtr address_functions = IntPtr.Add(handle, (int)export_header.AddressOfFunctions); | |
IntPtr address_names = IntPtr.Add(handle, (int)export_header.AddressOfNames); | |
//IntPtr address_nameordinals = IntPtr.Add(handle, (int)export_header.AddressOfNameOrdinals); | |
IntPtr func_exact_address = IntPtr.Zero; | |
string functionname=""; | |
//Enumerating exported functions from the module | |
for (int i = 0; i < no_of_names; i++) | |
{ | |
IntPtr func_name_address = IntPtr.Add(address_names, (sizeof(int)) * i); | |
int function_name_rva = Marshal.ReadInt32(func_name_address); | |
IntPtr func_name_string = IntPtr.Add(handle, function_name_rva); | |
functionname = Marshal.PtrToStringAnsi(func_name_string); | |
if (Gethashfromstring(functionname) == hash) | |
{ | |
Console.WriteLine("[+] Hash resolved to function: {0}", functionname); | |
IntPtr func_address = IntPtr.Add(address_functions, (sizeof(int)) * i); | |
int func_address_rva = Marshal.ReadInt32(func_address); | |
func_exact_address = IntPtr.Add(handle, func_address_rva); | |
//Console.WriteLine("[+] Function RVA: 0x{0:X}", func_address_rva.ToString("X")); | |
break; | |
} | |
} | |
Console.WriteLine("[+] Running " + functionname); | |
return func_exact_address; | |
} | |
} | |
class STRUCTS | |
{ | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
public struct STARTUPINFO | |
{ | |
public Int32 cb; | |
public string lpReserved; | |
public string lpDesktop; | |
public string lpTitle; | |
public Int32 dwX; | |
public Int32 dwY; | |
public Int32 dwXSize; | |
public Int32 dwYSize; | |
public Int32 dwXCountChars; | |
public Int32 dwYCountChars; | |
public Int32 dwFillAttribute; | |
public Int32 dwFlags; | |
public Int16 wShowWindow; | |
public Int16 cbReserved2; | |
public IntPtr lpReserved2; | |
public IntPtr hStdInput; | |
public IntPtr hStdOutput; | |
public IntPtr hStdError; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct PROCESS_INFORMATION | |
{ | |
public IntPtr hProcess; | |
public IntPtr hThread; | |
public int dwProcessId; | |
public int dwThreadId; | |
} | |
[Flags] | |
public enum ProcessCreationFlags : uint | |
{ | |
ZERO_FLAG = 0x00000000, | |
CREATE_BREAKAWAY_FROM_JOB = 0x01000000, | |
CREATE_DEFAULT_ERROR_MODE = 0x04000000, | |
CREATE_NEW_CONSOLE = 0x00000010, | |
CREATE_NEW_PROCESS_GROUP = 0x00000200, | |
CREATE_NO_WINDOW = 0x08000000, | |
CREATE_PROTECTED_PROCESS = 0x00040000, | |
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000, | |
CREATE_SEPARATE_WOW_VDM = 0x00001000, | |
CREATE_SHARED_WOW_VDM = 0x00001000, | |
CREATE_SUSPENDED = 0x00000004, | |
CREATE_UNICODE_ENVIRONMENT = 0x00000400, | |
DEBUG_ONLY_THIS_PROCESS = 0x00000002, | |
DEBUG_PROCESS = 0x00000001, | |
DETACHED_PROCESS = 0x00000008, | |
EXTENDED_STARTUPINFO_PRESENT = 0x00080000, | |
INHERIT_PARENT_AFFINITY = 0x00010000 | |
} | |
public struct IMAGE_DOS_HEADER | |
{ // DOS .EXE header | |
public UInt16 e_magic; // Magic number | |
public UInt16 e_cblp; // Bytes on last page of file | |
public UInt16 e_cp; // Pages in file | |
public UInt16 e_crlc; // Relocations | |
public UInt16 e_cparhdr; // Size of header in paragraphs | |
public UInt16 e_minalloc; // Minimum extra paragraphs needed | |
public UInt16 e_maxalloc; // Maximum extra paragraphs needed | |
public UInt16 e_ss; // Initial (relative) SS value | |
public UInt16 e_sp; // Initial SP value | |
public UInt16 e_csum; // Checksum | |
public UInt16 e_ip; // Initial IP value | |
public UInt16 e_cs; // Initial (relative) CS value | |
public UInt16 e_lfarlc; // File address of relocation table | |
public UInt16 e_ovno; // Overlay number | |
public UInt16 e_res_0; // Reserved words | |
public UInt16 e_res_1; // Reserved words | |
public UInt16 e_res_2; // Reserved words | |
public UInt16 e_res_3; // Reserved words | |
public UInt16 e_oemid; // OEM identifier (for e_oeminfo) | |
public UInt16 e_oeminfo; // OEM information; e_oemid specific | |
public UInt16 e_res2_0; // Reserved words | |
public UInt16 e_res2_1; // Reserved words | |
public UInt16 e_res2_2; // Reserved words | |
public UInt16 e_res2_3; // Reserved words | |
public UInt16 e_res2_4; // Reserved words | |
public UInt16 e_res2_5; // Reserved words | |
public UInt16 e_res2_6; // Reserved words | |
public UInt16 e_res2_7; // Reserved words | |
public UInt16 e_res2_8; // Reserved words | |
public UInt16 e_res2_9; // Reserved words | |
public UInt32 e_lfanew; // File address of new exe header | |
} | |
public struct SIGNATURE | |
{ | |
public UInt32 signature; | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
public struct IMAGE_FILE_HEADER | |
{ | |
public UInt16 Machine; | |
public UInt16 NumberOfSections; | |
public UInt32 TimeDateStamp; | |
public UInt32 PointerToSymbolTable; | |
public UInt32 NumberOfSymbols; | |
public UInt16 SizeOfOptionalHeader; | |
public UInt16 Characteristics; | |
} | |
public struct IMAGE_OPTIONAL_HEADER64 | |
{ | |
public UInt16 Magic; | |
public Byte MajorLinkerVersion; | |
public Byte MinorLinkerVersion; | |
public UInt32 SizeOfCode; | |
public UInt32 SizeOfInitializedData; | |
public UInt32 SizeOfUninitializedData; | |
public UInt32 AddressOfEntryPoint; | |
public UInt32 BaseOfCode; | |
public UInt64 ImageBase; | |
public UInt32 SectionAlignment; | |
public UInt32 FileAlignment; | |
public UInt16 MajorOperatingSystemVersion; | |
public UInt16 MinorOperatingSystemVersion; | |
public UInt16 MajorImageVersion; | |
public UInt16 MinorImageVersion; | |
public UInt16 MajorSubsystemVersion; | |
public UInt16 MinorSubsystemVersion; | |
public UInt32 Win32VersionValue; | |
public UInt32 SizeOfImage; | |
public UInt32 SizeOfHeaders; | |
public UInt32 CheckSum; | |
public UInt16 Subsystem; | |
public UInt16 DllCharacteristics; | |
public UInt64 SizeOfStackReserve; | |
public UInt64 SizeOfStackCommit; | |
public UInt64 SizeOfHeapReserve; | |
public UInt64 SizeOfHeapCommit; | |
public UInt32 LoaderFlags; | |
public UInt32 NumberOfRvaAndSizes; | |
public IMAGE_DATA_DIRECTORY ExportTable; | |
public IMAGE_DATA_DIRECTORY ImportTable; | |
public IMAGE_DATA_DIRECTORY ResourceTable; | |
public IMAGE_DATA_DIRECTORY ExceptionTable; | |
public IMAGE_DATA_DIRECTORY CertificateTable; | |
public IMAGE_DATA_DIRECTORY BaseRelocationTable; | |
public IMAGE_DATA_DIRECTORY Debug; | |
public IMAGE_DATA_DIRECTORY Architecture; | |
public IMAGE_DATA_DIRECTORY GlobalPtr; | |
public IMAGE_DATA_DIRECTORY TLSTable; | |
public IMAGE_DATA_DIRECTORY LoadConfigTable; | |
public IMAGE_DATA_DIRECTORY BoundImport; | |
public IMAGE_DATA_DIRECTORY IAT; | |
public IMAGE_DATA_DIRECTORY DelayImportDescriptor; | |
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; | |
public IMAGE_DATA_DIRECTORY Reserved; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct IMAGE_DATA_DIRECTORY | |
{ | |
public UInt32 VirtualAddress; | |
public UInt32 Size; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct IMAGE_EXPORT_DIRECTORY | |
{ | |
public UInt32 Characteristics; | |
public UInt32 TimeDateStamp; | |
public UInt16 MajorVersion; | |
public UInt16 MinorVersion; | |
public UInt32 Name; | |
public UInt32 Base; | |
public UInt32 NumberOfFunctions; | |
public UInt32 NumberOfNames; | |
public UInt32 AddressOfFunctions; // RVA from base of image | |
public UInt32 AddressOfNames; // RVA from base of image | |
public UInt32 AddressOfNameOrdinals; // RVA from base of image | |
} | |
[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)] | |
public delegate Boolean CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, STRUCTS.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STRUCTS.STARTUPINFO lpStartupInfo, out STRUCTS.PROCESS_INFORMATION lpProcessInformation); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
st = sys.argv[1] | |
def convert2hash(st): | |
t = 1 | |
sm = 0 | |
for i in st: | |
sm = sm*10 + (ord(i)%10) | |
print(sm) | |
convert2hash(st) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment