/////////////////////////////////////////////////////////////////////////////////
// Module32HLP.h
//

#pragma once


#ifndef __JUMP_IND_INSTRUCTION
#define __JUMP_IND_INSTRUCTION
#include "pshpack2.h"
struct JumpIndInstruction
{
    WORD    wJumpCode;          // Jump Instruction code = 0x25FF
    DWORD   pJumpAddress;       // Jump address
};
typedef  JumpIndInstruction* PJumpIndInstruction;
struct JumpIndInstAddress
{
    WORD    wJumpCode;          // Jump Instruction code = 0x25FF
#ifdef _AMD64_
    DWORD   dwJumpAddress;      // relative offset of jump address
#endif
    PBYTE   pJumpAddress;       // Jump address
};
typedef  JumpIndInstAddress* PJumpIndInstAddress;
#include "poppack.h"                    // Back to 4 byte packing
#endif

typedef PBYTE* PImportEntry;

typedef struct _REAL_EXPORT_DESCRIPTOR
{
    WORD    wOrderIndex;
    WORD    wOriginalOrderIndex;
    PCWSTR  cwsDllName;
    PCSTR   csExportName;
    PBYTE   pEntryPoint;
    PCSTR   csOriginalExportName;
} REAL_EXPORT_DESCRIPTOR, *PREAL_EXPORT_DESCRIPTOR, &RREAL_EXPORT_DESCRIPTOR;

typedef struct _REAL_IMPORT_DESCRIPTOR
{
    DWORD   dwThunkIndex;
    PCSTR   szCalledModuleName;
    WORD    wHint;
    WORD    wOrder;
    DWORD   dwTimeDateStamp;
    DWORD   dwForwarderChain;
    PCSTR   szFunctionName;
    PBYTE   pFunctionAddress;
} REAL_IMPORT_DESCRIPTOR, *PREAL_IMPORT_DESCRIPTOR, &RREAL_IMPORT_DESCRIPTOR;

class CModule32HLP  
{
public:
    CModule32HLP(
        HANDLE hProcessHandle = NtCurrentProcess()
        );
	virtual ~CModule32HLP( );

// Attributes
//private:
    HANDLE                  m_hProcessHandle;
    PEB_LDR_DATA            m_stModuleListTable;
    PPEB_LDR_DATA           m_pModuleListTable;
    LDR_DATA_TABLE_ENTRY    m_stModuleInfoEntry;
    PLDR_DATA_TABLE_ENTRY   m_pModuleInfoEntry;
    PLDR_DATA_TABLE_ENTRY   m_pHeaderEntry;
    WCHAR                   m_wsStringBuffer[260];
    CHAR                    m_sStringBuffer [260];
    IMAGE_NT_HEADERS        m_stPEImageHeaders;
    PBYTE                   m_pRemotePEHeaders;
    PBYTE                   m_pCopyOf_idata;
    DWORD                   m_dw_idataSize;

// Operations
//private:
    bool EvaluteForwardExport(
        PCSTR psForwardRef,
        RREAL_EXPORT_DESCRIPTOR rExportDescriptor
        );
public:
    PIMAGE_NT_HEADERS GetImageHeaders( );
    PLDR_DATA_TABLE_ENTRY FindModule( PCSTR psModuleName );
    PLDR_DATA_TABLE_ENTRY FindModule( HMODULE hModuleHandle );
    PLDR_DATA_TABLE_ENTRY FindModule( PCWSTR pwsModuleName );
    PWSTR GetModuleFileNameW( );
    PWSTR GetModuleNameW( );
    PLDR_DATA_TABLE_ENTRY GetNextModuleInfoEntry( );
    PLDR_DATA_TABLE_ENTRY GetFirstModuleInfoEntry( );
    PPEB_LDR_DATA GetModulesTableHeader( )
    { return m_pModuleListTable; }
    PBYTE m_pPebBaseAddress;
    PRTL_USER_PROCESS_PARAMETERS m_pProcessParameters;
    WCHAR m_wsProcessModuleFileName[260];
    WCHAR* m_pwsProcessModuleFileName;
    HINSTANCE m_hImageBaseAddress;
    DWORD m_dw_idataRVA;
    BYTE* m_pRemote_idata;
    IMAGE_IMPORT_DESCRIPTOR* m_pCopyImpDirectoty;
    PLDR_DATA_TABLE_ENTRY FindModuleByAddress(DWORD_PTR dwAddress);
    WCHAR m_wsCurrentDirectory[260];
    bool EnumExportStart(PCWSTR pwsModuleName);
    bool GetExportByName(
        PCSTR sExportName,
        RREAL_EXPORT_DESCRIPTOR rExportDescriptor
        );
    CHAR m_sExportName[512];
    bool EnumExportNext(RREAL_EXPORT_DESCRIPTOR rExportDescriptor);
    PIMAGE_EXPORT_DIRECTORY m_pExportDirectory;
    PDWORD m_pAddressOfFunctions;
    PDWORD m_pAddressOfNames;
    PWORD m_pAddressOfNameOrdinals;
    DWORD m_nFunctions;
    DWORD m_nNames;
    DWORD m_dwNameIndx;
    PBYTE m_pCopyOf_edata;
    DWORD_PTR m_dwUpdateAddr;
    PBYTE m_pImageBase;
    DWORD m_dwExportTableRVA;
    DWORD m_dw_edataSize;
    void EnumExportStop();
    WCHAR m_wsLastModuleName[260];
    CHAR m_sLastExportName[260];
    bool EnumImportStart(PCWSTR pwsModuleName);
    PIMAGE_IMPORT_DESCRIPTOR m_pImportDescriptor;
    DWORD_PTR m_dwImportUpdateValue;
    void EnumImportStop();
    bool EnumImportNext(RREAL_IMPORT_DESCRIPTOR rImportDescriptor);
    PIMAGE_THUNK_DATA m_pThunkDataArray;
    PBYTE* m_pImportThunkArray;
    PBYTE m_pIporterModule;
};
