【滴水逆向P77】加载进程(PE查看器)应用程序源码解析(下)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【滴水逆向P77】加载进程(PE查看器)应用程序源码解析

GetDlgItem函数

MSDN官方文档解释GetDlgItem函数

函数功能:获取指定对话框中控件的句柄。

函数原型:

HWND GetDlgItem(
  [in, optional] HWND hDlg,
  [in]           int  nIDDlgItem
);

参数说明:

  • hDlg:对话框句柄,我们需要获取哪个对话框中控件的句柄,就把这个对话框的句柄写入
    nIDDlgItem:要检索的控件标识符
    返回值:函数成功,则返回控件的句柄。

ListView_InsertColumn宏

MSDN官方文档解释ListView_InsertColumn宏

功能:在列表视图控件中加入新列

宏原型:

void ListView_InsertColumn(
   hwnd,
   iCol,
   pcol
);

参数说明:

hwnd:列表视图控件的句柄。

iCol:新列的索引。

pcol:包含指向新列属性的LVCOLUMN结构体指针。

5.初始化模块列表

VOID InitMoudleListView(HWND hDlg) {
  //设置窗口风格需要调用结构体
  LV_COLUMN lv;
  HWND hListMoudles;
  //初始化
  memset(&lv, 0, sizeof(LV_COLUMN));
  //获取模块列表句柄
  hListMoudles = GetDlgItem(hDlg, IDC_LIST_MOUDLE);
  //设置整行选中
  SendMessage(hListMoudles, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
  //第一列:
  lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
  lv.pszText = (LPWSTR)TEXT("模块名称");
  lv.cx = 330;
  lv.iSubItem = 0;
  //ListView_Insertcolumn(hListMoudles,0,&lv);
  SendMessage(hListMoudles, LVM_INSERTCOLUMN, 0, (DWORD)&lv);
  //第二列:
  lv.pszText = (LPWSTR)TEXT("模块位置");
  lv.cx = 330;
  lv.iSubItem = 1;
  SendMessage(hListMoudles, LVM_INSERTCOLUMN, 0, (DWORD)&lv);
}

这段代码使用的函数和宏跟初始化进程的相差不多,这里不做过多赘述。

我们来看看初始化过后的窗口:

5.向列表视图控件中展示数据

由于我们还没有了解加载windows所有进程的API,所以我们先来学习一下如何让列表视图控件中显示数据:

这段代码中是向列表视图控件中加入了假的数据,是我们指定的数据,下一篇文章将会向大家介绍加载Windows所有进程的API:

VOID EnumProcess(HWND hListProcess) {
  LV_ITEM vitem;
  //初始化,第一个进程
  memset(&vitem, 0, sizeof(LV_ITEM));
  vitem.mask = LVIF_TEXT;
  //假数据:
  vitem.pszText = (LPWSTR)TEXT("csrss.exe");
  vitem.iItem = 0;
  vitem.iSubItem = 0;
  //ListView_Insertem(hListProcess,*vitem);
  SendMessage(hListProcess, LVM_INSERTITEM, 0, (DWORD)&vitem);
  vitem.pszText = (LPWSTR)TEXT("448");
  vitem.iItem = 0;
  vitem.iSubItem = 1;
  SendMessage(hListProcess, LVM_SETITEM, 0, (DWORD)&vitem);
  //ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("56590000");
  vitem.iItem = 0;
  vitem.iSubItem = 2;
  ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("000F0000");
  vitem.iItem = 0;
  vitem.iSubItem = 3;
  ListView_SetItem(hListProcess, &vitem);
  //第二个进程假数据:
  vitem.pszText = (LPWSTR)TEXT("QQ.exe");
  vitem.iItem = 1;
  vitem.iSubItem = 0;
  SendMessage(hListProcess, LVM_INSERTITEM, 0, (DWORD)&vitem);
  vitem.pszText = (LPWSTR)TEXT("153");
  vitem.iItem = 1;
  vitem.iSubItem = 1;
  ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("65580000");
  vitem.iItem = 1;
  vitem.iSubItem = 2;
  ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("001E0000");
  vitem.iItem = 1;
  vitem.iSubItem = 3;
  ListView_SetItem(hListProcess, &vitem);
  //第三个进程假数据:
  vitem.pszText = (LPWSTR)TEXT("WeChat.exe");
  vitem.iItem = 2;
  vitem.iSubItem = 0;
  SendMessage(hListProcess, LVM_INSERTITEM, 0, (DWORD)&vitem);
  vitem.pszText = (LPWSTR)TEXT("256");
  vitem.iItem = 2;
  vitem.iSubItem = 1;
  ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("75960000");
  vitem.iItem = 2;
  vitem.iSubItem = 2;
  ListView_SetItem(hListProcess, &vitem);
  vitem.pszText = (LPWSTR)TEXT("015B0000");
  vitem.iItem = 2;
  vitem.iSubItem = 3;
  ListView_SetItem(hListProcess, &vitem);
}

LV_ITEM结构体

向列表视图控件中加入数据的时候,我们使用到了该结构体。

MSDN官方文档解释LV_ITEM结构体

结构体用途:用于指定或接收列表视图项的属性。

这个结构和前面的哪个LV_COLUMN结构体很像。实际上就是为了满足各种消息的需求,定义了不同的结构体。

结构体原型:

typedef struct tagLVITEMA {
  UINT   mask;
  int    iItem;
  int    iSubItem;
  UINT   state;
  UINT   stateMask;
  LPSTR  pszText;
  int    cchTextMax;
  int    iImage;
  LPARAM lParam;
  int    iIndent;
  int    iGroupId;
  UINT   cColumns;
  PUINT  puColumns;
  int    *piColFmt;
  int    iGroup;
} LVITEMA, *LPLVITEMA;

参数说明:

  • mask:指定有效的成员,比如我们需要使用pszText字段,就要声明LVIF_TEXT。
    iItem:此结构引用的项从零开始的索引。
    iSubItem:此结构引用的子项的一个基于索引,如果此结构是引用项而不是子项,则为0。
    state:指示项的状态,状态图像和覆盖图像。
    stateMask:指定将检索或修改 状态 成员的位的值。
    pszText:指向包含结束符文本的字符串。
    cchTextMax:pszText指向的缓冲区的大小。
    iImage:控件图像列表中的项图标的索引。
    lParam:特定于项的值。
    iIndent:要缩进项的图像宽度数。。
    iGroupId:项所属的组的标识符。

ListView_SetItem宏

MSDN官方文档解释ListView_SetItem宏

宏功能:设置列表视图项的某些或全部属性。

宏原型:

void ListView_SetItem(
   hwnd,
   pitem
);

参数解释:

  • hwnd:列表视图控件的句柄。
  • pitem:指向包含项属性的LVITEM结构体。

这里必须得提一句,只有在列表视图控件增添第一行的时候,使用ListView_InsertItem宏,在添加子项的时候,要使用ListView_SetItem宏!!!

如果使用错误,则不能成功添加子项。

向模块列表视图控件中展示数据

VOID EnumMoudles(HWND hListProcess, WPARAM wParam, LPARAM lParam) {
  DWORD dwRowId;
  TCHAR szPid[21];
  LV_ITEM lv;
  //初始化
  memset(&lv, 0, sizeof(LV_ITEM));
  //获取选择行
  dwRowId = SendMessage(hListProcess, LVM_GETNEXTITEM,-1 , LVNI_SELECTED);
  if (dwRowId == -1) {
    MessageBox(NULL, TEXT("请选择进程"), TEXT("出错啦"), MB_OK);
    return;
  }
  //获取PID
  lv.iSubItem = 1;
  lv.pszText = szPid;
  lv.cchTextMax = 0x20;
  SendMessage(hListProcess, LVM_GETITEMTEXT, dwRowId, (DWORD)&lv);
  MessageBox(NULL, szPid, TEXT("PID"), MB_OK);
}

这里需要注意一点,我们要获取进程使用的模块,必须根据PID来获取,所以当点击进程模块中的项目的时候,要想办法把PID传过来。

函数使用的跟前面的差不多,不做过多赘述了。

我们来看看最后的效果:



相关文章
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
66 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
52 0
|
1月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
59 0
|
1月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
78 0
|
1天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
9 2
|
2天前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
11天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
39 4
|
12天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
14天前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
35 3
|
1月前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
53 5

推荐镜像

更多