【Windows核心编程实验一】实现windows程序和进程编程

Windows核心编程系列文章仅作为实验报告和Windows编程学习参考,不作为任何技术文章,还望大佬们勿喷。

具体的系列文章想访问我的语雀:https://www.yuque.com/sunj3t

1. 实验名称

实现windows程序和进程编程

2. 实验环境

  1. VC6.0++
  2. Windows 7

3. 实验目的

  1. 完成一个Windows程序,并掌握进程的概念、进程的状态
  2. 下载process Explorer软件和spy++软件,使用这两款软件工具对内核对象,进程和线程相关信息进行查看。
  3. 要求应用采用进程函数实现一个应用程序
    • 创建进程的方法,结束进程方程;
    • 掌握进程间通信。
    • 内存地址的写入和查询

4. 实验内容、步骤及结果

1. 实验内容

  1. 使用process Explorer软件和Spy++,并学会使用软件,查看内核对象,理解内核对象,进程概念。
  2. 通过创建子进程,打开记事本程序,并调用CreateToolhelp32Snapshot查找测试程序,然后调用ReadProcessMemory查找需要读的值的地址,然后通过writeProcessMemory写入。

2. 实验步骤

  1. 学会使用procexp
procexp

Procexp除了可以查看进程,还可以拿来结束进程,重启进程等

procexp
  1. 学会使用spy++
spy++

可以看到每个进程以及其线程的地址信息

  1. 要求应用采用进程函数实现一个应用程序
    (1). 创建进程的方法,结束进程方程;
int main(int argc, char* argv[])
{
    TCHAR  szFileName[] = TEXT("Notepad");
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    ::CreateProcess(NULL, szFileName, NULL, NULL, FALSE,CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);  // 关闭线程句柄,既然我们不使用它
    ::CloseHandle(pi.hThread);
    g_hProcess = pi.hProcess;
    printf("进程ID:%d,线程ID:%d\n", pi.dwProcessId, pi.dwThreadId);
    Sleep(100);
    ::CloseHandle(g_hProcess);
    return 0;
}

(2). 掌握进程间通信。

HWND nphWnd = ::FindWindow("Notepad", NULL);
    if (nphWnd)
    {
        int iVal;
        printf(" Input val = ");    // 输入修改的值
        scanf("%d", &iVal);
        
        FindFirst(iVal);    // 进行第一次查找

        ShowList(); // 打印出搜索的结果
        while (g_nListCnt > 1)
        {
            printf(" Input val = ");
            scanf("%d", &iVal);
            FindNext(iVal); // 进行下次搜索
            ShowList(); // 显示搜索结果
        }

        printf(" New value = ");    // 取得新值
        scanf("%d", &iVal); // 写入新值
        if (WriteMemory(g_arList[0], iVal))
            printf(" Write data success \n");
    }
    else
    {
        ::MessageBox(NULL, TEXT("please open notepad"), TEXT("error"), MB_OK);
        return 0;
    }

(3). 内存地址的写入和查询

BOOL CompareAPage(DWORD dwBaseAddr, DWORD dwValue)
{
    BYTE arBytes[4096]; // 读取1页内存
    if (!::ReadProcessMemory(g_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL))
        return FALSE;   // 此页不可读

    DWORD* pdw; // 在这1页内存中查找
    for (int i = 0; i<(int)4 * 1024 - 3; i++)
    {
        pdw = (DWORD*)&arBytes[i];
        if (pdw[0] == dwValue)  // 等于要查找的值?
        {
            if (g_nListCnt >= 1024)
                return FALSE;
            // 添加到全局变量中
            g_arList[g_nListCnt++] = dwBaseAddr + i;
        }
    }

    return TRUE;
}

BOOL FindFirst(DWORD dwValue)
{
    const DWORD dwOneGB = 1024 * 1024 * 1024;   // 1GB
    const DWORD dwOnePage = 4 * 1024;       // 4KB

    if (g_hProcess == NULL)
        return FALSE;

    DWORD dwBase;   // 查看操作系统类型,以决定开始地址
    OSVERSIONINFO vi = { sizeof(vi) };
    ::GetVersionEx(&vi);
    if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
        dwBase = 4 * 1024 * 1024;       // Windows 98系列,4MB 
    else
        dwBase = 640 * 1024;        // Windows NT系列,64KB

    for (; dwBase < 2 * dwOneGB; dwBase += dwOnePage)   // 在开始地址到2GB的地址空间进行查找
    {
        CompareAPage(dwBase, dwValue);  // 比较1页大小的内存
    }

    return TRUE;
}

BOOL FindNext(DWORD dwValue)
{
    int nOrgCnt = g_nListCnt;   // 保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
    g_nListCnt = 0; // 在m_arList数组记录的地址处查找
    BOOL bRet = FALSE;  // 假设失败 
    DWORD dwReadValue;
    for (int i = 0; i<nOrgCnt; i++)
    {
        if (::ReadProcessMemory(g_hProcess, (LPVOID)g_arList[i], &dwReadValue, sizeof(DWORD), NULL))
        {
            if (dwReadValue == dwValue)
            {
                g_arList[g_nListCnt++] = g_arList[i];
                bRet = TRUE;
            }
        }
    }

    return bRet;
}

void ShowList() // 打印出搜索到的地址
{
    for (int i = 0; i< g_nListCnt; i++)
    {
        printf("%08lX \n", g_arList[i]);
    }
}

BOOL WriteMemory(DWORD dwAddr, DWORD dwValue)
{
    return ::WriteProcessMemory(g_hProcess, (LPVOID)dwAddr, &dwValue, sizeof(DWORD), NULL);
}

3. 实验结果(实验运行截图)

输入修改的值:

输入修改的值

取得新值并写入新值:

取得新值并写入新值

5. 实验中的问题及心得

  • 一开始使用VS2015去编译老师给的相关代码和书上的代码,发现会爆很多错误,后面发现是因为版本太高,好一些函数在新版本并不能使用。所以最后我还是使用的vc作为编译器。
  • 如果不在查找程序之前让程序稍停一会儿,那么FindWindow()函数会直接执行完毕而导致判断nphWnd时会认为程序并没有打开。所以需要在FindWindow()函数前加上sleep()函数。
  • 对windows的API调用时要注意每个函数的参数的作用,以及参数的类型,如果类型不匹配的话也是不能够成功调用的。

6. 附件

以下是实验代码

链接:https://pan.baidu.com/s/1Ytldu_4DypGdyGEIUCaIHQ
提取码:yaxi

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 5,878评论 3 28
  • 1.内存的页面置换算法 (1)最佳置换算法(OPT)(理想置换算法):从主存中移出永远不再需要的页面;如无这样的...
    杰伦哎呦哎呦阅读 3,095评论 1 9
  • 【贝弗】命中注定 00 “话说,你们知道吗?最近这一带出现了一个很厉害的术士哦。幻术很厉害,还到处挑事,一副看不起...
    Franr17阅读 322评论 0 2
  • 【山语】不仅提供温暖舒适的住宿条件和环境,同时也是约拍场地的不二之选。作为好吃、馋嘴的重庆人,店主(茜茜、羲仔、老...
    陳浅浅阅读 126评论 0 0