题目:编写一个程序(比如kernel module),使附件2.c中的程序跳出死循环。2.c中的代码如下:
#include 
int main(int argc, char *argv[])
{
int n = 1;
printf(“Address of n :%x\n”,&n);
printf(“My pid is: %d.\n”, getpid());
while(1){
sleep(3); /* sleep for 3 secs */
}
printf(“I break out\n”);
return 0;
}
说明:
此题只需上交实现文档、源码。源码中请以注释注明平台、系统。比如32位linux 3.2。
将上述代码编译好(不能修改),运行,想办法令其跳出循环,打印出”I break out\n”。
你的代码不能调用任何其他软件,比如od之类。
如果你知道内核栈、pt_regs结构体、函数栈桢,那么你很有可能成功。
成功打印出”I break out\n”但同时引发段错误得2/3分。

屌丝不会linux,所以只能windows

思路:debug编译出上面代码可以看到while(1)的反汇编代码为mov ecx,1,只需用WriteProcessMemory将1修改为0即可跳出死循环

反汇编:

 0040D470 >                push ebp
0040D471 8BEC mov ebp,esp
0040D473 83EC sub esp,
0040D476 push ebx
0040D477 push esi
0040D478 push edi
0040D479 8D7D BC lea edi,dword ptr ss:[ebp-]
0040D47C B9 mov ecx,
0040D481 B8 CCCCCCCC mov eax,CCCCCCCC
0040D486 F3:AB rep stos dword ptr es:[edi]
0040D488 C745 FC >mov dword ptr ss:[ebp-],
0040D48F 8D45 FC lea eax,dword ptr ss:[ebp-]
0040D492 push eax
0040D493 942F4200 push xd_code2.00422F94 ; ASCII "Address of n :%x
"
0040D498 E8 call xd_code2.printf
0040D49D 83C4 add esp,
0040D4A0 E8 4B000000 call xd_code2._getpid
0040D4A5 push eax
0040D4A6 842F4200 push xd_code2.00422F84 ; ASCII "My pid is: %d.
"
0040D4AB E8 call xd_code2.printf
0040D4B0 83C4 add esp,
0040D4B3 B9 mov ecx, ; while()
0040D4B8 85C9 test ecx,ecx
0040D4BA je short xd_code2.0040D4CF
0040D4BC 8BF4 mov esi,esp
0040D4BE 6A push
0040D4C0 FF15 18A24200 call dword ptr ds:[<&KERNEL32.Sleep>] ; kernel32.Sleep
0040D4C6 3BF4 cmp esi,esp
0040D4C8 E8 C33BFFFF call xd_code2.
0040D4CD ^ EB E4 jmp short xd_code2.0040D4B3
0040D4CF 1C204200 push xd_code2.0042201C ; ASCII "I break out
"
0040D4D4 E8 call xd_code2.printf
0040D4D9 83C4 add esp,
0040D4DC 33C0 xor eax,eax
0040D4DE 5F pop edi
0040D4DF 5E pop esi
0040D4E0 5B pop ebx
0040D4E1 83C4 add esp,
0040D4E4 3BEC cmp ebp,esp
0040D4E6 E8 A53BFFFF call xd_code2.
0040D4EB 8BE5 mov esp,ebp
0040D4ED 5D pop ebp
0040D4EE C3 retn

代码:

 #include "stdafx.h"
#include <windows.h>
#include <TlHelp32.h>
#define PID 2200 //每次运行手动修改
BYTE* GetBase(int Pid); int _tmain(int argc, _TCHAR* argv[])
{
BYTE *base = GetBase(PID); //printf_s("%x", base);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
byte NewCode = ; //测试发现地址不会变,都为0x40D4B4,故GetBase函数都不需要
if (WriteProcessMemory(hProcess, base + 0xD4B4, &NewCode, , NULL))
{
printf_s("Write Success!\n");
} getchar();
return ;
} BYTE* GetBase(int Pid)
{
BYTE *result = NULL;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid);
if (hSnap == INVALID_HANDLE_VALUE)
{
printf_s("CreateToolhelp32Snapshot failed\n");
} MODULEENTRY32 Me32;
Me32.dwSize = sizeof(MODULEENTRY32); BOOL bRet = Module32First(hSnap, &Me32);
while(bRet)
{
if (Me32.th32ProcessID == Pid)
{
printf_s("Have Found!\n");
result = Me32.modBaseAddr; //返回主模块的基地址
break;
}
bRet = Module32Next(hSnap, &Me32);
} CloseHandle(hSnap);
return result;
}

运行效果:

跳出成功

总结:

while(1)在debug编译下为mov ecx,1  test ecx, ecx, jz XXXXXXXX ,根据这个就可以写入数据了。

XDCTF 2013 code2 跳出死循环的更多相关文章

  1. while循环条件不成立却无法跳出死循环的问题

    在进入循环的时候,实际上是将A从内存加载到寄存器里面运行的,在整个循环中,A这个变量都只是在读取寄存器里面的值. 而当进入中断的时候,中断里面会从内存加载A到寄存器,修改完之后又存到内存里,然后退出中 ...

  2. Java Socket 死循环while如何判断客户端断开

    多线程的服务器程序 线程中等待客户端的消息    我的代码能实现服务器与客户端的通信    问题是: 当客户端中断或退出  以上代码却不能判断Socket中断 跳不出while的无限循环 解决方法: ...

  3. 关于死循环while(true){}或for(;;){}的总结

    关于死循环while(true){}或for(;;){}的总结 1.基本用法: while(true){     语句体; } for(;;){     语句体; } 以上情况,语句体会一直执行. 2 ...

  4. python之最强王者(3)——变量,条件、循环语句

    1.Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的 ...

  5. Java Concurrent之 AbstractQueuedSynchronizer

    ReentrantLock/CountDownLatch/Semaphore/FutureTask/ThreadPoolExecutor的源码中都会包含一个静态的内部类Sync,它继承了Abstrac ...

  6. Unsafe的应用

    要想把java并发包学好,并明白其底层的设计原理,Unsafe类你不能不去研究一下.下面介绍一下Unsafe类的功能以及它在JDK中的应用. 一.分配内存和释放内存 功能:类中提供的3个本地方法all ...

  7. Java并发编程:Timer和TimerTask(转载)

    Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...

  8. 20 BasicTaskScheduler0 基本任务调度类基类(二)——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  9. Timer与TimerTask的真正原理&使用介绍

    转载: Timer与TimerTask的真正原理&使用介绍 其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来 ...

随机推荐

  1. 2014鞍山直播比赛H称号HDU5077(DFS修剪+通过计)

    NAND Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Sub ...

  2. jquery 重复事件

    采用jquery时刻.其他活动均达到. 相反1对1的. 例如:onclick="$(document).keypress(function (key) {  if (key.keyCode ...

  3. Group and sum array of hashes by date

    I have an array of hashes like this: [{:created=>Fri, 22 Jan 2014 13:02:13 UTC +00:00, :amount=&g ...

  4. Errors occurred during the build. Errors running builder &#39;JavaScript Validator&#39; on

    eclipse又一次编译时候就会报错Errors occurred during the build. Errors running builder 'JavaScript Validator' on ...

  5. java设计模式之一工厂模式

    简单工厂模式是java设计模式中最简单的设计模式之一: 工厂模式是最常用的设计模式之一. 工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模 ...

  6. [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

    原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...

  7. ASP.NET中 RegularExpressValidator(正则验证)的使用

    原文:ASP.NET中 RegularExpressValidator(正则验证)的使用 ylbtech-ASP.NET-Control-Validator: RegularExpressValida ...

  8. 初探Django线程发送邮件

    最近一直在纠结一个邮件发送的问题. 在本地Linux下搭建程序,不填写EMAIL设置就可以成功发送邮件,在远端的云服务器下的Linux环境就发送不了.在windows下搭建的程序也不能发送注册邮件,很 ...

  9. sql点滴37—mysql中的错误Data too long for column '' at row 1

    原文:sql点滴37-mysql中的错误Data too long for column '' at row 1   1.MYSQL服务 我的电脑——(右键)管理——服务与应用程序——服务——MYSQ ...

  10. weblogic启动报错--com.octetstring.vde.backend.BackendRoot

    错误现象: 使用bea用户启动weblogic时报错,错误信息如下: <2014-7-29 下午07时47分23秒 CST> <Notice> <Log Manageme ...