📄 hexview.c
字号:
#include <windows.h>
#include "hexview.h"
#define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (s))
#define xfree(p) HeapFree(GetProcessHeap(), 0, (p))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define EM_TEXT 0
#define EM_HEX_HIGH 1
#define EM_HEX_LOW 2
#define GWL_HEXINFO 0
#define WM_MOUSEWHEEL 0x020A
#define HV_COLOR_DEFAULT 0
#define HV_COLOR_RED 1
#define HV_COLOR_SBGRAY 2
#define HV_COLOR_GREEN 3
#define HV_COLOR_BLUE 4
typedef struct _HV_PRINTFMT
{
BYTE x;
BYTE y;
BYTE color : 7;
BYTE highlight : 1;
BYTE len;
BYTE data[];
} HV_PRINTFMT, *PHV_PRINTFMT;
typedef struct _HV_MODIFYLOG
{
int nLog;
int nBack;
int nMaxUndoLog;
int nMaxRedoLog;
PBYTE pLog;
PBYTE pLogBuf;
DWORD nLogBufLen;
DWORD nMaxLogBuf;
PBYTE pOrgBuf;
DWORD nOrgBufLen;
} HV_MODIFYLOG, *PHV_MODIFYLOG;
typedef struct _HEXVIEW
{
BOOL TextOnly;
BOOL ReadOnly;
BOOL NoCursor;
PBYTE Buffer;
DWORD Length;
DWORD BaseAddress;
ULONG SelStart;
ULONG SelEnd;
DWORD PageOffset;
DWORD PageLength;
DWORD PageMaxLength;
UINT LineWidth;
UINT AddressWidth;
UINT CharWidth;
UINT CharHeight;
DWORD EditMode;
int Cursor;
HV_MODIFYLOG hv_modl;
DWORD color[10];
} HEXVIEW, *PHEXVIEW;
void *HV_MemSearchR(void *m1, size_t n1, void *m2, size_t n2)
{
unsigned char *s1 = m1;
unsigned char *s2 = m2;
size_t i, index[256];
if (n1 < n2)
return NULL;
if (n2 == 0)
return m1;
for (i = 0; i < 256; i++)
index[i] = n2 + 1;
for (i = 0; i < n2; i++)
index[s2[i]] = n2 - i;
do
{
for (i = 0; s1[i] == s2[i]; i++)
{
if (i == n2 - 1)
return s1;
}
s1 += index[s1[n2]];
} while (s1 + n2 <= (char *)m1 + n1);
return NULL;
}
void *HV_MemSearchL(void *m1, size_t n1, void *m2, size_t n2)
{
unsigned char *s1 = m1;
unsigned char *s2 = m2;
size_t i, index[256];
if (n1 < n2)
return NULL;
if (n2 == 0)
return m1;
for (i = 0; i < 256; i++)
index[i] = n2 + 1;
for (i = n2 - 1; i >= 0; i--)
index[s2[i]] = n2 - i;
do
{
for (i = n2 - 1; s1[i] == s2[i]; i--)
{
if (i == 0)
return s1;
}
s1 -= index[*(s1 - 1)];
} while (s1 >= (char *)m1 + n2);
return NULL;
}
int HV_InitModifyLog(PHV_MODIFYLOG hv_modl, PBYTE pOrgBuf, DWORD pOrgLen)
{
hv_modl->nLog = 0;
hv_modl->nBack = 0;
hv_modl->nMaxUndoLog = 0;
hv_modl->nMaxRedoLog = 0;
hv_modl->pOrgBuf = pOrgBuf;
hv_modl->nOrgBufLen = pOrgLen;
hv_modl->nMaxLogBuf = 0x200000;
hv_modl->nLogBufLen = 0x8000;
hv_modl->pLogBuf = VirtualAlloc(NULL, hv_modl->nMaxLogBuf, MEM_RESERVE, PAGE_READWRITE);
hv_modl->pLog = hv_modl->pLogBuf;
if (hv_modl->pLogBuf == NULL)
return -1;
VirtualAlloc(hv_modl->pLogBuf, hv_modl->nLogBufLen, MEM_COMMIT, PAGE_READWRITE);
return 0;
}
int HV_AddModifyLog(PHV_MODIFYLOG hv_modl, DWORD offset, DWORD length, PBYTE pData)
{//*
int n;
PBYTE p;
DWORD l;
if (hv_modl->nLog < 0)
{
hv_modl->nBack += -hv_modl->nLog;
hv_modl->nMaxUndoLog -= -hv_modl->nLog;
hv_modl->nLog = 0;
}
p = hv_modl->pLog;
n = hv_modl->nLog;
for (; n > 0; n--)
p += *(PDWORD)p + sizeof(DWORD) + sizeof(DWORD);
if (hv_modl->nLogBufLen - (p - hv_modl->pLogBuf) < length + sizeof(DWORD) + sizeof(DWORD))
{
l = MAX(0x8000, length + sizeof(DWORD) + sizeof(DWORD));
l = (l + 0x7fff) & ~0x7fff;
if (hv_modl->nLogBufLen + l > hv_modl->nMaxLogBuf)
return -1;
hv_modl->nLogBufLen += l;
VirtualAlloc(hv_modl->pLogBuf, hv_modl->nLogBufLen, MEM_COMMIT, PAGE_READWRITE);
}
*((PDWORD)p)++ = length;
*((PDWORD)p)++ = offset;
memcpy(p, pData, length);
hv_modl->nLog++;
hv_modl->nMaxRedoLog = hv_modl->nLog;//*/
return 0;
}
int HV_GetModifyData(PHV_MODIFYLOG hv_modl, DWORD nStart, PBYTE pBuffer, DWORD nSize)
{
int n, x;
PBYTE pUndoLog = hv_modl->pLog;
PBYTE pRedoLog = hv_modl->pLog;
DWORD off, len;
DWORD nEnd = nStart + nSize;
if (hv_modl->nLog > hv_modl->nMaxRedoLog || hv_modl->nLog < hv_modl->nMaxUndoLog)
return -1;
x = MIN(hv_modl->nOrgBufLen - nStart, nSize);
memcpy(pBuffer, hv_modl->pOrgBuf + nStart, x); //拷贝原始数据
for (n = 0; n < hv_modl->nBack; n++)
{
len = *((PDWORD)pUndoLog - 1);
off = *((PDWORD)pUndoLog - 2);
pUndoLog -= len + sizeof(DWORD) + sizeof(DWORD);
if (off >= nStart && off < nEnd)
{
int l = MIN(len, nSize - (off - nStart));
memcpy(pBuffer + (off - nStart), pUndoLog, l);
}
else if (off >= nStart && off <= nEnd)
{
int l = MIN(nEnd - off, len);
memcpy(pBuffer + off - nStart, pUndoLog, l);
}
}
if (hv_modl->nLog >= 0)
{
for (n = 0; n < hv_modl->nLog; n++)
{
len = *((PDWORD)pRedoLog)++;
off = *((PDWORD)pRedoLog)++;
if (off >= nStart && off < nEnd)
{
int l = MIN(len, nSize - (off - nStart));
memcpy(pBuffer + (off - nStart), pRedoLog, l);
}
else if (off >= nStart && off <= nEnd)
{
int l = MIN(nEnd - off, len);
memcpy(pBuffer + off - nStart, pRedoLog, l);
}
pRedoLog += len;
}
}
else
{
for (n = 0; n > hv_modl->nLog; n--)
{
len = *((PDWORD)pUndoLog - 1);
off = *((PDWORD)pUndoLog - 2);
pUndoLog -= len + sizeof(DWORD) + sizeof(DWORD);
if (off >= nStart && off < nEnd)
{
int l = MIN(len, nSize - (off - nStart));
memcpy(pBuffer + (off - nStart), pUndoLog, l);
}
else if (off >= nStart && off <= nEnd)
{
int l = MIN(nEnd - off, len);
memcpy(pBuffer + off - nStart, pUndoLog, l);
}
}
}
return x;//*/
}
void HV_ApplyModifyLog(PHV_MODIFYLOG hv_modl, PBYTE pNewBuffer)
{
int i, j;
PBYTE pUndoLog = hv_modl->pLog;
PBYTE pRedoLog = hv_modl->pLog;
if (pNewBuffer)
{
memcpy(pNewBuffer, hv_modl->pOrgBuf, hv_modl->nOrgBufLen);
hv_modl->pOrgBuf = pNewBuffer;
}
if (hv_modl->nLog == 0 && hv_modl->nBack == 0)
return;
for (i = 0; i < hv_modl->nBack; i++)
{
DWORD len = *((PDWORD)pUndoLog - 1);
DWORD off = *((PDWORD)pUndoLog - 2);
pUndoLog -= sizeof(DWORD) + sizeof(DWORD) + len;
for (j = 0; (DWORD)j < len; j++)
hv_modl->pOrgBuf[off + j] = pUndoLog[j];
}
if (hv_modl->nLog >= 0)
{
for (i = 0 ; i < hv_modl->nLog; i++)
{
DWORD len = *((PDWORD)pRedoLog)++;
DWORD off = *((PDWORD)pRedoLog)++;
for (j = 0; (DWORD)j < len; j++)
{
pUndoLog[j] = hv_modl->pOrgBuf[off + j];
hv_modl->pOrgBuf[off + j] = pRedoLog[j];
}
pUndoLog += len;
pRedoLog += len;
*((PDWORD)pUndoLog)++ = off;
*((PDWORD)pUndoLog)++ = len;
}
}
else
{
for (i = 0 ; i > hv_modl->nLog; i--)
{
DWORD len = *--((PDWORD)pUndoLog);
DWORD off = *--((PDWORD)pUndoLog);
pUndoLog -= len;
pRedoLog -= len;
for (j = 0; (DWORD)j < len; j++)
{
pRedoLog[j] = hv_modl->pOrgBuf[off + j];
hv_modl->pOrgBuf[off + j] = pUndoLog[j];
}
*--((PDWORD)pRedoLog) = off;
*--((PDWORD)pRedoLog) = len;
}
}
hv_modl->pLog = pUndoLog;
hv_modl->nMaxRedoLog -= hv_modl->nLog;
hv_modl->nMaxUndoLog += -hv_modl->nLog;
hv_modl->nLog = 0;
hv_modl->nBack = 0;
}
int HV_DelModifyLog(PHV_MODIFYLOG hv_modl)
{
if (hv_modl->nLog < 0)
{
PBYTE p = hv_modl->pLog;
int i, j;
for (i = hv_modl->nLog; i < 0; i++)
{
DWORD len = *((PDWORD)p - 1);
DWORD off = *((PDWORD)p - 2);
p -= sizeof(DWORD) + sizeof(DWORD) + len;
for (j = len; j > 0; j--)
p[sizeof(DWORD) + sizeof(DWORD) + j] = p[j];
*((PDWORD)p + 0) = len;
*((PDWORD)p + 1) = off;
}
hv_modl->pLog = p;
hv_modl->nMaxRedoLog = -hv_modl->nLog;
hv_modl->nMaxUndoLog -= hv_modl->nLog;
hv_modl->nLog = 0;
}
else
{
hv_modl->nMaxRedoLog = hv_modl->nLog;
}
return 0;
}
void HV_FreeModifyLog(PHV_MODIFYLOG hv_modl)
{
hv_modl->nLog = 0;
hv_modl->nBack = 0;
hv_modl->nMaxUndoLog = 0;
hv_modl->nMaxRedoLog = 0;
hv_modl->pLog = NULL;
hv_modl->pOrgBuf = NULL;
hv_modl->nOrgBufLen = 0;
hv_modl->nMaxLogBuf = 0;
hv_modl->nLogBufLen = 0;
VirtualFree(hv_modl->pLogBuf, 0, MEM_RELEASE);
hv_modl->pLogBuf = NULL;
}
void HV_ResetModifyLog(PHV_MODIFYLOG hv_modl, PBYTE pOrgBuf, DWORD pOrgLen)
{
hv_modl->nLog = 0;
hv_modl->nBack = 0;
hv_modl->nMaxUndoLog = 0;
hv_modl->nMaxRedoLog = 0;
hv_modl->pOrgBuf = pOrgBuf;
hv_modl->nOrgBufLen = pOrgLen;
}
int HV_LogUndo(HWND hWnd, BOOL bTest)
{
PHEXVIEW p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
NMHDR n;
if (p->hv_modl.nLog > p->hv_modl.nMaxUndoLog)
{
if (bTest == TRUE)
return 1;
else
{
p->hv_modl.nLog--;
RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
n.code = HV_EN_CHANGE;
n.idFrom = GetDlgCtrlID(hWnd);
n.hwndFrom = hWnd;
SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
return 1;
}
}
return 0;
}
int HV_LogRedo(HWND hWnd, BOOL bTest)
{
PHEXVIEW p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
NMHDR n;
if (p->hv_modl.nLog < p->hv_modl.nMaxRedoLog)
{
if (bTest == TRUE)
return 1;
else
{
p->hv_modl.nLog++;
RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
n.code = HV_EN_CHANGE;
n.idFrom = GetDlgCtrlID(hWnd);
n.hwndFrom = hWnd;
SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
return 1;
}
}
return 0;
}
int HV_Compare(PBYTE s1, PBYTE s2, int n)
{
int i = n;
if (*s1 == *s2)
{
while (--n && *++s1 == *++s2);
return i - n;
}
else
{
while (--n && *++s1 != *++s2);
return n - i;
}
}
void HV_FormatForPrint(int lineWidth, int maxLine, DWORD startAddr, PVOID allModify, PBYTE data,
DWORD selStart, DWORD selEnd, PBYTE output)
{
PHV_PRINTFMT hv_pfmt;
PBYTE buf = output;
BYTE text[64 * 32];
int i, j, k, l, w, dlen;
BOOL bModify, bHighLight;
lineWidth = MAX(lineWidth, 1);
lineWidth = MIN(lineWidth, 32);
maxLine = MAX(maxLine, 1);
maxLine = MIN(maxLine, 64);
dlen = HV_GetModifyData(allModify, startAddr, text, lineWidth * maxLine);
maxLine = dlen / lineWidth;
maxLine += (dlen % lineWidth) == 0 ? 0 : 1;
w = lineWidth;
for (i = 0; i < maxLine; i++)
{
hv_pfmt = (PHV_PRINTFMT)buf; //输出地址
hv_pfmt->x = 1;
hv_pfmt->y = i;
hv_pfmt->color = HV_COLOR_ADDR;
hv_pfmt->highlight = 0;
hv_pfmt->len = 8;
buf += sizeof(HV_PRINTFMT);
for (l = 3; l >= 0; l--)
{
*buf++ = "0123456789ABCDEF"[(startAddr >> (l * 8 + 4)) & 15];
*buf++ = "0123456789ABCDEF"[(startAddr >> (l * 8 + 0)) & 15];
}
if (i == maxLine - 1)
{
if (dlen % lineWidth)
w = dlen % lineWidth;
}
for (j = 0; j < w; j += k)
{
k = HV_Compare(data + startAddr + j, text + i * lineWidth + j, w - j);
if (k > 0)
{
bModify = FALSE;
}
else
{
bModify = TRUE;
k = -k;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -