rtoss - Rev 298

Subversion Repositories:
Rev:

#include "Common.h"
#include "HexEditWnd.h"

//
// constants
//
#define          CUT_CHAR             0x18
#define          COPY_CHAR            0x03
#define          PASTE_CHAR           0x16
#define          STRZ_CHAR            0x1a

//
// global variables
//

BOOL UnHookHexEditbox(HWND hEdit) {
        char clsName[256];
        GetClassName(hEdit, clsName, sizeof(clsName));

        if (stricmp("ComboBox", clsName) == 0) {
                hEdit = GetWindow(hEdit, GW_CHILD);
        }

        GetClassName(hEdit, clsName, sizeof(clsName));
        WNDCLASS  wc;
        GetClassInfo(NULL, clsName, &wc);

        if (SetWindowLong(
                hEdit,
                GWL_WNDPROC,
                (DWORD)wc.lpfnWndProc))
                return TRUE;
        else
                return FALSE;
}

//
// window proc stub for hex editbox's
//
BOOL HookHexEditbox(HWND hEdit)
{
        char clsName[256];
        GetClassName(hEdit, clsName, sizeof(clsName));

        if (stricmp("ComboBox", clsName) == 0) {
                hEdit = GetWindow(hEdit, GW_CHILD);
        }

        if (SetWindowLong(
                hEdit,
                GWL_WNDPROC,
                (DWORD)HexOnlyEditProc))
                return TRUE;
        else
                return FALSE;
}

//
// call this with an edit box as argument to monitor the occurrence of the ENTER key
//
BOOL HookEditboxEnter(HWND hEdit)
{
        char clsName[256];
        GetClassName(hEdit, clsName, sizeof(clsName));

        if (stricmp("ComboBox", clsName) == 0) {
                hEdit = GetWindow(hEdit, GW_CHILD);
        }

        if (SetWindowLong(
                hEdit,
                GWL_WNDPROC,
                (DWORD)EditHookEnterProc))
                return TRUE;
        else
                return FALSE;
}

LRESULT __stdcall HexOnlyEditProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
        CHAR      c = 0;
        /*
        char      cBuff[9], *pCH;
        DWORD     dw;
        */

        WNDCLASS  wc;

        switch(Msg)
        {
        case WM_PASTE:
                // check whether the contents is a valid hex number string
                if (OpenClipboard(hWnd))
                {
                        int             len;
                        char    *pData;

                        if (IsClipboardFormatAvailable(cf16Edit)) {
                                PHE_CLIPBOARD_DATA      pcbd;

                                pcbd = (PHE_CLIPBOARD_DATA)::GetClipboardData(cf16Edit);
                                len = pcbd->dwDataSize;
                                pData = (char *)&pcbd->byDataStart;
                        } else if (IsClipboardFormatAvailable(CF_TEXT)) {
                                pData = (char *)::GetClipboardData(CF_TEXT);
                                len = strlen(pData);
                        } else {
                                return 0;
                        }

                        for (int i = 0; i < len; i++) {
                                int ch1 = (pData[i] & 0xF0) >> 4;
                                int ch2 = (pData[i] & 0x0F);

                                if (ch1 >= 0 && ch1 <= 9) {
                                        ch1 += 0x30;
                                } else {
                                        ch1 += 'A' - 0xA;
                                }
                                PostMessage(hWnd, WM_CHAR, ch1, 0);

                                if (ch2 >= 0 && ch2 <= 9) {
                                        ch2 += 0x30;
                                } else {
                                        ch2 += 'A' - 0xA;
                                }
                                PostMessage(hWnd, WM_CHAR, ch2, 0);
                        }
                        CloseClipboard();
                        /*
                        pCH = (char*)GetClipboardData(EnumClipboardFormats(CF_LOCALE)); // for win2k
                        if (!pCH)
                                pCH = (char*)GetClipboardData(EnumClipboardFormats(0));
                        CloseClipboard();
                        if (pCH)
                                if (lstrcpyn(cBuff, pCH, sizeof(cBuff)))
                                        if (HexStrToInt(cBuff, &dw))
                                                break;                 
                        */

                }
                return 0;

        case WM_KEYDOWN:
                // inform parent window via WM_COMMAND msg about ENTER key occurrence
                switch(wParam)
                {
                case VK_RETURN:
                        SendMessage(
                                GetParent(hWnd),
                                WM_COMMAND,
                                MAKEWPARAM(GetDlgCtrlID(hWnd), NM_HEXEDITENTER),
                                (LPARAM)hWnd);
                        return 0;

                //case VK_ESCAPE:
                        // if the control handles this key it'll close the parent dlg - dunno why :(
                //      return 0;
                }
                break;

        case WM_CHAR:
                // force hex characters
                if (wParam != VK_BACK    &&
                   wParam  != CUT_CHAR   &&
                   wParam  != PASTE_CHAR &&
                   wParam  != COPY_CHAR  &&
                   wParam  != STRZ_CHAR)        
                {
                        c = toupper(wParam);
                        if ( (c < '0' || c > '9') &&
                                 (c < 'A' || c > 'F'))
                                 return 0;
                        else
                                wParam = c;
                }
                break;
        }

        char clsName[256];
        GetClassName(hWnd, clsName, sizeof(clsName));

        // get default edit wnd proc
        GetClassInfo(NULL, clsName, &wc);

        return CallWindowProc(wc.lpfnWndProc, hWnd, Msg, wParam, lParam);
}

LRESULT __stdcall EditHookEnterProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
        WNDCLASS  wc;

        switch(Msg)
        {
        case WM_KEYDOWN:
                // inform parent window via WM_COMMAND msg about ENTER key occurrence
                switch(wParam)
                {
                case VK_RETURN:
                        SendMessage(
                                GetParent(hWnd),
                                WM_COMMAND,
                                MAKEWPARAM(GetDlgCtrlID(hWnd), NM_HEXEDITENTER),
                                (LPARAM)hWnd);
                        return 0;

                //case VK_ESCAPE:
                        // if the control handles this key it'll close the parent dlg - dunno why :(
                //      return 0;
                }
                break;
        }

        char clsName[256];
        GetClassName(hWnd, clsName, sizeof(clsName));
        GetClassInfo(NULL, clsName, &wc);

        return CallWindowProc(wc.lpfnWndProc, hWnd, Msg, wParam, lParam);
}

//
// convert a hex number string to a DW
//
BOOL HexStrToInt(char *szHexStr, DWORD *pdwHexVal)
{
        char   *pCH, c;
        DWORD  dwVal = 0, dw;

        pCH = szHexStr;
        while (*pCH)
        {
                c = toupper(*pCH++);
                if (c >= 'A' && c <= 'F')
                        dw = (DWORD)c - ((DWORD)'A' - 10);
                else if (c >= '0' && c <= '9')
                        dw = (DWORD)c - (DWORD)'0';
                else
                        return FALSE; // invalid hex char
                dwVal = (dwVal << 4) + dw;
        }

        *pdwHexVal = dwVal;
        return TRUE;
}

/*
 * Return DWORD
 *              2 : EXE
 *              1 : DLL
 *              0 : NOT PE
 */

DWORD file_type(char *base) {
        IMAGE_DOS_HEADER *dos_head = (IMAGE_DOS_HEADER *)base;
        IMAGE_NT_HEADERS *header;
        DWORD type;

        if (dos_head->e_magic != IMAGE_DOS_SIGNATURE) {
                return 0;
        }

        header = (IMAGE_NT_HEADERS *)((char *)dos_head + dos_head->e_lfanew);
        if (IsBadReadPtr(header, sizeof(*header))) {
                return 0;
        }
        if (header->Signature != IMAGE_NT_SIGNATURE) {
                return 0;
        }

        if (header->FileHeader.Characteristics & IMAGE_FILE_DLL) {
                type = 1;
        } else {
                type = 2;
        }

        return type;
}

#define isin(address,start,length) ((address)>=(start) && (address)<(start)+(length))
/*
 * Get the vitual offset from file offset
 */

int get_va(char *base, DWORD file_offset) {
        IMAGE_DOS_HEADER *dos_head = (IMAGE_DOS_HEADER *)base;
        IMAGE_NT_HEADERS *header;
        IMAGE_SECTION_HEADER *section_header;
        int   sect;

        header = (IMAGE_NT_HEADERS *)((char *)dos_head + dos_head->e_lfanew);
        for (sect = 0, section_header = (IMAGE_SECTION_HEADER *)
                ((char *)header + header->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
                sect < header->FileHeader.NumberOfSections; sect++, section_header++) {
                if (isin(file_offset, section_header->PointerToRawData, section_header->SizeOfRawData)) {
                        return section_header->VirtualAddress +
                                file_offset - section_header->PointerToRawData + header->OptionalHeader.ImageBase;
                }
        }
        return file_offset;
}

/*
 * Get the file offset from vitual offset
 */

int get_fo(char *base, DWORD va_offset) {
        IMAGE_DOS_HEADER *dos_head = (IMAGE_DOS_HEADER *)base;
        IMAGE_NT_HEADERS *header;
        IMAGE_SECTION_HEADER *section_header;
        int   sect;
        DWORD   va;

        header = (IMAGE_NT_HEADERS *)((char *)dos_head + dos_head->e_lfanew);
        va = va_offset - header->OptionalHeader.ImageBase;

        for (sect = 0, section_header = (IMAGE_SECTION_HEADER *)
                ((char *)header + header->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
                sect < header->FileHeader.NumberOfSections; sect++, section_header++) {
                if (isin(va, section_header->VirtualAddress, section_header->SizeOfRawData)) {
                        return section_header->PointerToRawData + va - section_header->VirtualAddress;
                }
        }
        return va_offset;
}