public void ExecuteDllMain(Image image, DllCallType callType) { uint addressOfEntryPoint = Environment.Is64BitProcess ? image.OptionalHeader64->AddressOfEntryPoint : image.OptionalHeader32->AddressOfEntryPoint; if (addressOfEntryPoint >= image.Size - sizeof(IntPtr)) { throw new LoadFailedException("Cannot invoke this library's DllMain() function; its address is invalid."); } IntPtr callback = (IntPtr)(image.BasePtr + addressOfEntryPoint); DllEntryProc dllEntryProc = (DllEntryProc)Marshal.GetDelegateForFunctionPointer(callback, typeof(DllEntryProc)); uint succeeded = dllEntryProc((IntPtr)image.BasePtr, callType, IntPtr.Zero); if (succeeded == 0) { throw new LoadFailedException("This library's DllMain() function returned false in response to " + callType + "."); } }
public void ExecuteTlsFunctions(Image image, DllCallType callType) { IMAGE_DATA_DIRECTORY directory = Environment.Is64BitProcess ? image.OptionalHeader64->TLSTable : image.OptionalHeader32->TLSTable; if (directory.VirtualAddress == 0) { return; } if (directory.VirtualAddress > image.Size - sizeof(IntPtr)) { throw new LoadFailedException("This library's TLS table is damaged or invalid."); } IMAGE_TLS_DIRECTORY32 *tlsDirectory32 = (IMAGE_TLS_DIRECTORY32 *)(image.BasePtr + directory.VirtualAddress); IntPtr callbacks = (IntPtr)tlsDirectory32->AddressOfCallBacks; IntPtr endPtr = (IntPtr)(image.BasePtr + image.Size - sizeof(IntPtr)); if (callbacks != IntPtr.Zero) { IntPtr callback; while ((callback = *(IntPtr *)callbacks) != IntPtr.Zero) { if ((long)callback > (long)endPtr) { throw new LoadFailedException("One of this library's TLS functions is damaged or invalid."); } DllEntryProc dllEntryProc = (DllEntryProc)Marshal.GetDelegateForFunctionPointer(callback, typeof(DllEntryProc)); uint succeeded = dllEntryProc((IntPtr)image.BasePtr, DllCallType.PROCESS_ATTACH, IntPtr.Zero); if (succeeded == 0) { throw new LoadFailedException("One of this library's TLS functions returned false in response to " + callType + "."); } } } }