|
本帖最后由 diddom 于 2012-5-23 01:45 编辑
很棒的入门款式
纯win32的唷,有ListView且双色item
Hook地方还用红色字标示
ListS_SSDT_win32.rar
(22.33 KB, 下载次数: 6)
- // SystemTool.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "resource.h"
- #include <stdio.h>
- #include <windows.h>
- #include <winnt.h>
- #include <WindowsX.h>
- #include <commctrl.h>
- #pragma comment(lib,"comctl32")
- typedef ULONG NTSTATUS;
- #define MAX_LOADSTRING 100
- #define SystemModuleInformation 11
- #define ibaseDD *(PDWORD)&ibase
-
- HINSTANCE g_hInst;
- HWND hWinMain;
- HWND hList;
- #define ID_LISTVIEW 1001
-
- #define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))
- #define ibaseDD *(PDWORD)&ibase
- #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
- #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
-
- typedef struct
- {
- WORD offset:12;
- WORD type:4;
- } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
-
-
- typedef
- ULONG
- (WINAPI *ZWQUERYSYSTEMINFORMATION)
- (
- DWORD SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
- );
- ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;
-
- typedef enum _SYSDBG_COMMAND {
- SysDbgReadVirtualMemory = 8,
- SysDbgWriteVirtualMemory = 9,
- } SYSDBG_COMMAND, *PSYSDBG_COMMAND;
-
- typedef struct _MEMORY_CHUNKS
- {
- ULONG Address;
- PVOID Data;
- ULONG Length;
- } MEMORY_CHUNKS, *PMEMORY_CHUNKS;
-
- typedef
- NTSTATUS
- (NTAPI * ZWSYSTEMDEBUGCONTROL)
- (
- SYSDBG_COMMAND ControlCode,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength,
- PULONG ReturnLength
- );
-
- ZWSYSTEMDEBUGCONTROL ZwSystemDebugControl = NULL;
-
- typedef struct _SYSTEM_MODULE_INFORMATION { //Information Class 11
- ULONG Reserved[2];
- PVOID Base;
- ULONG Size;
- ULONG Flags;
- USHORT Index;
- USHORT Unknown;
- USHORT LoadCount;
- USHORT ModuleNameOffset;
- CHAR ImageName[256];
- } SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
-
-
- typedef struct
- {
- CHAR fname[100];
- ULONG address1;
- ULONG address2;
- } SSDT_LIST_ENTRY;
-
- SSDT_LIST_ENTRY ssdt_list[500];
- //ssdt_list = new SSDT_LIST_ENTRY[500];
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
- // Foward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- BOOL LocateNtdllEntry();
- BOOL DebugPrivilege(TCHAR *PName,BOOL bEnable);
- void InitListView();
- void GetSSDT();
- void FindExport();
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- // TODO: Place code here.
- MSG msg;
- HACCEL hAccelTable;
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_SYSTEMTOOL, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SYSTEMTOOL);
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- //delete [] ssdt_list;
- return msg.wParam;
- }
- //
- // FUNCTION: MyRegisterClass()
- //
- // PURPOSE: Registers the window class.
- //
- // COMMENTS:
- //
- // This function and its usage is only necessary if you want this code
- // to be compatible with Win32 systems prior to the 'RegisterClassEx'
- // function that was added to Windows 95. It is important to call this function
- // so that the application will get 'well formed' small icons associated
- // with it.
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SYSTEMTOOL);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = (LPCSTR)IDC_SYSTEMTOOL;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
- return RegisterClassEx(&wcex);
- }
- //
- // FUNCTION: InitInstance(HANDLE, int)
- //
- // PURPOSE: Saves instance handle and creates main window
- //
- // COMMENTS:
- //
- // In this function, we save the instance handle in a global variable and
- // create and display the main program window.
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // Store instance handle in our global variable
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
- NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- hWinMain = hWnd;
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- //
- // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
- //
- // PURPOSE: Processes messages for the main window.
- //
- // WM_COMMAND - process the application menu
- // WM_PAINT - Paint the main window
- // WM_DESTROY - post a quit message and return
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- TCHAR szHello[MAX_LOADSTRING];
- LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
- switch (message)
- {
- case WM_NOTIFY:
- switch (LOWORD(wParam))
- {
- case ID_LISTVIEW:
- //LPNMHDR pnm = (LPNMHDR)lParam;
- //if(pnm->hwndFrom != m_hWnd)
- //SendMessage(pnm->hwndFrom,msg,wParam,lParam);
- //LPNMHDR pnm = (LPNMHDR) lParam;
- //if(pnm->code == NM_CUSTOMDRAW)
- if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW)
- {
- //LPNMLVCUSTOMDRAW lpLVCD = (LPNMLVCUSTOMDRAW) lParam;
- //switch(lpLVCD->nmcd.dwDrawStage)
- switch(((LPNMLVCUSTOMDRAW)lParam)->nmcd.dwDrawStage)
- {
- case CDDS_PREPAINT:
- return CDRF_NOTIFYITEMDRAW;
- case CDDS_ITEMPREPAINT:
- { //設置不同顏色
- LPNMLVCUSTOMDRAW customDraw = (LPNMLVCUSTOMDRAW) lParam;
- customDraw->clrTextBk=customDraw->nmcd.dwItemSpec%2?RGB(250, 250, 250):RGB(0xFF, 0xFF, 0xFF);
- if (ssdt_list[customDraw->nmcd.dwItemSpec].address1 != ssdt_list[customDraw->nmcd.dwItemSpec].address2) customDraw->clrText = RGB(255, 0, 0) ;
- else customDraw->clrText = RGB(0, 0, 0) ;
- return CDRF_NEWFONT;
- }
- break;
- default:
- return CDRF_DODEFAULT;
- }
- }
- if(((LPNMHDR)lParam)->code == WM_ERASEBKGND)
- {
- int ii;
- ii = 0;
- }
- break;
-
- }
- break;
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case IDM_ABOUT:
- DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
-
- case WM_ERASEBKGND:
- //return TRUE;
- break;
-
- case WM_SIZE:
- MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
- break;
- case WM_CREATE:
- hWinMain = hWnd;
- InitListView();
- LocateNtdllEntry();
- FindExport();
- DebugPrivilege(SE_DEBUG_NAME,TRUE);
- GetSSDT();
- return 0;
- break;
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- // TODO: Add any drawing code here...
- RECT rt;
- GetClientRect(hWnd, &rt);
- DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
- EndPaint(hWnd, &ps);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- // Mesage handler for about box.
- LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- //////////////////////////////////////////////////////////////////////////
- //
- //
- BOOL LocateNtdllEntry()
- {
- HMODULE ntdll_dll = NULL;
-
- if (!(ntdll_dll = GetModuleHandle("ntdll.dll"))) return FALSE;
- if (!( ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(ntdll_dll, "ZwQuerySystemInformation" )))
- return FALSE;
- if (!( ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(ntdll_dll, "ZwSystemDebugControl" )))
- return FALSE;
-
- return TRUE;
- }
-
- //////////////////////////////////////////////////////////////////////////
- //
- //
- BOOL DebugPrivilege(TCHAR *PName,BOOL bEnable)
- {
- BOOL fOk = FALSE;
- HANDLE hToken;
- TOKEN_PRIVILEGES tp;
-
- if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken))
- {
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
- LookupPrivilegeValue(NULL,PName,&tp.Privileges[0].Luid);
- AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
- fOk=(GetLastError() == ERROR_SUCCESS);
- CloseHandle(hToken);
- }
- return fOk;
- }
- //////////////////////////////////////////////////////////////////////////
- //
- //
- DWORD GetHeaders(PCHAR ibase,
- PIMAGE_FILE_HEADER *pfh,
- PIMAGE_OPTIONAL_HEADER *poh,
- PIMAGE_SECTION_HEADER *psh)
-
- {
- PIMAGE_DOS_HEADER mzhead = (PIMAGE_DOS_HEADER)ibase;
-
- if ((mzhead->e_magic != IMAGE_DOS_SIGNATURE) || (ibaseDD[mzhead->e_lfanew] != IMAGE_NT_SIGNATURE))
- return FALSE;
-
- *pfh = (PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew];
- if (((PIMAGE_NT_HEADERS)*pfh)->Signature != IMAGE_NT_SIGNATURE)
- return FALSE;
- *pfh = (PIMAGE_FILE_HEADER)((PBYTE)*pfh + sizeof(IMAGE_NT_SIGNATURE));
-
- *poh = (PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh + sizeof(IMAGE_FILE_HEADER));
- if ((*poh)->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
- return FALSE;
-
- *psh = (PIMAGE_SECTION_HEADER)((PBYTE)*poh + sizeof(IMAGE_OPTIONAL_HEADER));
-
- return TRUE;
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- //
- //
- void FindExport()
- {
- PIMAGE_FILE_HEADER pfh;
- PIMAGE_OPTIONAL_HEADER poh;
- PIMAGE_SECTION_HEADER psh;
- PIMAGE_EXPORT_DIRECTORY ped;
- DWORD* arrayOfFunctionNames;
- DWORD* arrayOfFunctionAddresses;
- WORD* arrayOfFunctionOrdinals;
- DWORD functionOrdinal;
- DWORD functionAddress;
- HMODULE hNtdll = GetModuleHandle(TEXT("ntdll.dll"));
- GetHeaders((PCHAR)hNtdll, &pfh, &poh, &psh);
- if (poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
- {
- ped = (PIMAGE_EXPORT_DIRECTORY)(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (BYTE*)hNtdll);
-
- arrayOfFunctionNames = (DWORD*)(ped->AddressOfNames + (BYTE*)hNtdll);
- arrayOfFunctionAddresses = (DWORD*)((BYTE*)hNtdll + ped->AddressOfFunctions);
- arrayOfFunctionNames = (DWORD*)((BYTE*)hNtdll + ped->AddressOfNames);
- arrayOfFunctionOrdinals = (WORD*)((BYTE*)hNtdll + ped->AddressOfNameOrdinals);
-
- for (int i=0; i < ped->NumberOfNames; i++)
- {
- char* fun_name = (char*)((BYTE*)hNtdll + arrayOfFunctionNames[i]);
-
- functionOrdinal = arrayOfFunctionOrdinals[i] + ped->Base - 1;
-
- functionAddress = (DWORD)((BYTE*)hNtdll + arrayOfFunctionAddresses[functionOrdinal]);
-
- if (fun_name[0] == 'N' && fun_name[1] == 't')
- {
- WORD number = *((WORD*)(functionAddress + 1));
-
- if (number>ped->NumberOfNames) continue;
-
- lstrcpy(ssdt_list[number].fname, fun_name);
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //
- //
- DWORD FindKiServiceTable(HMODULE hModule, DWORD dwKSDT)
- {
- PIMAGE_FILE_HEADER pfh;
- PIMAGE_OPTIONAL_HEADER poh;
- PIMAGE_SECTION_HEADER psh;
- PIMAGE_BASE_RELOCATION pbr;
- PIMAGE_FIXUP_ENTRY pfe;
-
- DWORD dwFixups = 0, i, dwPointerRva, dwPointsToRva, dwKiServiceTable;
- BOOL bFirstChunk;
-
- GetHeaders((PCHAR)hModule, &pfh, &poh, &psh);
-
- // loop thru relocs to speed up the search
- if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&
- (!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED)))
- {
-
- pbr = (PIMAGE_BASE_RELOCATION) RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, hModule);
-
- bFirstChunk = TRUE;
-
- // 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
- while (bFirstChunk || pbr->VirtualAddress)
- {
- bFirstChunk = FALSE;
-
- pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));
-
- for (i=0; i < (pbr->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1; i++, pfe++)
- {
- if (pfe->type == IMAGE_REL_BASED_HIGHLOW)
- {
- dwFixups++;
- dwPointerRva = pbr->VirtualAddress + pfe->offset;
- // DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed
- dwPointsToRva = *(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;
-
- // does this reloc point to KeServiceDescriptorTable.Base?
- if (dwPointsToRva == dwKSDT)
- {
- // check for mov [mem32],imm32. we are trying to find
- // "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"
- // from the KiInitSystem.
- if (*(PWORD)((DWORD)hModule + dwPointerRva-2) == 0x05c7)
- {
- // should check for a reloc presence on KiServiceTable here
- // but forget it
- dwKiServiceTable = *(PDWORD)((DWORD)hModule + dwPointerRva + 4) - poh->ImageBase;
- return dwKiServiceTable;
- }
- }
-
- }
- // should never get here
- }
- *(PDWORD)&pbr += pbr->SizeOfBlock;
- }
- }
-
- return 0;
- }
-
- DWORD dwKSDT; // rva of KeServiceDescriptorTable
- DWORD dwKiServiceTable; // rva of KiServiceTable
- DWORD dwKernelBase, dwServices = 0;
- //////////////////////////////////////////////////////////////////////////
- //
- //
- void GetSSDT()
- {
- HMODULE hKernel;
- PCHAR pKernelName;
- PDWORD pService;
- PIMAGE_FILE_HEADER pfh;
- PIMAGE_OPTIONAL_HEADER poh;
- PIMAGE_SECTION_HEADER psh;
- ULONG n;
-
- // get system modules - ntoskrnl is always first there
- ZwQuerySystemInformation(SystemModuleInformation, &n, 0, &n);
-
- PULONG p = new ULONG[n];
- ZwQuerySystemInformation(SystemModuleInformation, p, n * sizeof(*p), 0);
-
- PSYSTEM_MODULE_INFORMATION module = PSYSTEM_MODULE_INFORMATION(p+1);
-
- // imagebase
- dwKernelBase = (DWORD)module->Base;
-
- USHORT ofs = module->ModuleNameOffset;
- char* imgName = (char*)module->ImageName;
- pKernelName = ofs + imgName;
- // filename - it may be renamed in the boot.ini
- pKernelName = module->ModuleNameOffset + module->ImageName;
-
- // map ntoskrnl - hopefully it has relocs
- hKernel = LoadLibraryEx(pKernelName, 0, DONT_RESOLVE_DLL_REFERENCES);
-
- if(!hKernel) {
- return;
- }
-
- // our own export walker is useless here - we have GetProcAddress :)
- if (!(dwKSDT = (DWORD)GetProcAddress(hKernel, "KeServiceDescriptorTable"))) {
- return;
- }
-
- // get KeServiceDescriptorTable rva
- dwKSDT -= (DWORD)hKernel;
- // find KiServiceTable
- if (!(dwKiServiceTable = FindKiServiceTable(hKernel, dwKSDT))) {
- return;
- }
-
- // let's dump KiServiceTable contents
-
- // MAY FAIL!!!
- // should get right ServiceLimit here, but this is trivial in the kernel mode
- GetHeaders((PCHAR)hKernel, &pfh, &poh, &psh);
- dwServices = 0;
-
- for (pService = (PDWORD)((DWORD)hKernel+dwKiServiceTable);
- *pService - poh->ImageBase < poh->SizeOfImage;
- pService++, dwServices++)
- {
- ssdt_list[dwServices].address1 = *pService - poh->ImageBase + dwKernelBase;
- }
- FreeLibrary(hKernel);
- MEMORY_CHUNKS QueryBuff;
- DWORD *address2 = new DWORD[dwServices];
- QueryBuff.Address = dwKernelBase+dwKiServiceTable;
- QueryBuff.Data = address2;
- QueryBuff.Length = sizeof(DWORD)*dwServices;
-
- DWORD ReturnLength;
- ZwSystemDebugControl(
- SysDbgReadVirtualMemory,
- &QueryBuff, sizeof(MEMORY_CHUNKS), NULL,
- 0, &ReturnLength);
-
- LV_ITEM lvi;
- lvi.mask = LVIF_TEXT;
- char tmp[10];
- ListView_DeleteAllItems(hList);
- for (int j=0; j < dwServices; j++)
- {
- lvi.iItem = j;
- lvi.iSubItem = 0;
- lvi.pszText = tmp;
- wsprintf(tmp, "0x%02X", j);
- ListView_InsertItem(hList, &lvi);
- ListView_SetItemText(hList, j, 1, ssdt_list[j].fname);
- wsprintf(tmp, "0x%08X", ssdt_list[j].address1);
- ListView_SetItemText(hList, j, 2, tmp);
- wsprintf(tmp,"0x%08X", address2[j]);
- ssdt_list[j].address2 = address2[j];
- ListView_SetItemText(hList, j, 3, tmp);
- for(int i=0; i < *p; i++)
- {
- if (ssdt_list[j].address2 > (DWORD)module[i].Base&&ssdt_list[j].address2 < (DWORD)module[i].Base+module[i].Size)
- {
- ListView_SetItemText(hList, j, 4, module[i].ImageName);
- break;
- }
- }
- }
-
- delete [] p;
- delete [] address2;
- }
- void InitListView()
- {
- INITCOMMONCONTROLSEX iex;
- iex.dwSize = sizeof(iex);
- iex.dwICC=ICC_LISTVIEW_CLASSES;
- InitCommonControlsEx(&iex);
- hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL,
- WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHAREIMAGELISTS,
- 0, 0, 0, 0, hWinMain, (HMENU)ID_LISTVIEW, g_hInst, NULL);
- SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_GRIDLINES);
- LV_COLUMN lvc;
- lvc.mask = LVCF_TEXT | LVCF_WIDTH ;
- lvc.fmt = LVCFMT_RIGHT;
- lvc.pszText = "No.";
- lvc.cx = 50;
- SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM)&lvc);
-
- lvc.mask |= LVCF_FMT;
- lvc.fmt = LVCFMT_LEFT;
-
- lvc.pszText = "Function Name";
- lvc.cx = 350;
- SendMessage(hList, LVM_INSERTCOLUMN, 1, (LPARAM)&lvc);
- lvc.pszText = "OrgAddr";
- lvc.cx = 100;
- SendMessage(hList, LVM_INSERTCOLUMN, 2, (LPARAM)&lvc);
- lvc.pszText = "HookAddr";
- lvc.cx = 100;
- SendMessage(hList, LVM_INSERTCOLUMN, 3, (LPARAM)&lvc);
- lvc.pszText = "Module";
- lvc.cx = 200;
- SendMessage(hList, LVM_INSERTCOLUMN, 4, (LPARAM)&lvc);
- }
-
复制代码 |
|