首页
社区
课程
招聘
堆栈数据如何修改
发表于: 2010-10-5 20:37 9330

堆栈数据如何修改

2010-10-5 20:37
9330
我不知道要怎么描术这个问题,也许是描术不准确导致很多高手的回答让我一知半解,但为了工作,我又不得不厚着脸皮再问这个问题,且这个问题需要配合几张图来说明,图是从OD里面抓的
但发现在这里不可以放图进来,只能用文字来说明
第一,调试A程序到0040E1D2处
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
0040E1D6  |.  52            push    edx                              ; /pAddr
0040E1D7  |.  66:894424 0A  mov     word ptr [esp+A], ax             ; |
0040E1DC  |.  FF15 B8E54300 call    dword ptr [<&WS2_32.#11>]        ; \inet_addr
我们看到mov edx,dword ptr[esp+1C]所指向的是堆栈段如下图
Stack ss:[0012EBC4]=0012F018, (ASCII "192.168.1.180")
edx=00000038
我们点一下转入下面一个窗口跟踪
0012F018  31 39 32 2E 31 36 38 2E 31 2E 31 38 30 00 30 00  192.168.1.180.0.
0012F028  0D 00 00 00 0F 00 00 00 D6 F6 BA 26 AC F1 12 00  .......嘱?.
0012F038  33 CF 43 00 01 00 00 00 CE D7 41 00 01 00 00 00  3螩....巫A....

在这里,大家都知道,我们可以通过直接修改下面的192.168.1.180
改成192.168.1.1
是的,在OD里面是可以这样改的,但我的问题还没有提出,我要做的是,我想用win32汇编来写一个程序,主要功能如下,一,我们打开这个进程用CreateProcess
然后我再用VirtualAllocEx在在目标进程中申请一段内存,假如申请到的是00140000这个段,同时我们在自己的程序一开始定义了一个常量,如szIP  db '192.168.1.1',0,当申请到内存后,我们将上面的常赋给目标进程,同时修改上面
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
0040E1D6  |.  52            push    edx                              ; /pAddr
这两句为
push 00140000
这样一来
函数inet_addr所需的一个参数就满足了我们的要求
写内存用WriteProcessMemory函数,可是不成功,
再此,我想请教告位高手,要完成上面的工作,我需要怎做,不一定用我的办法
为方便高手指出不足,我特意将自己的代码贴在下面

.586
.model flat,stdcall
option casemap:none

;====Include文件=================
include include\windows.inc
include include\kernel32.inc
include include\user32.inc
include include\gdi32.inc

;====Lib文件=====================
includelib lib\kernel32.lib
includelib lib\user32.lib
includelib lib\gdi32.lib

;===========EQU数据======================================
M_BaseAddress        equ        0040E1D2h        ;要读写的地址(mov edx,dword ptr [esp+1C])

;===========已初始化的数据===============================
.data

;===========未初始化的数据===============================
.data?
stStartUp        STARTUPINFO                <>                ;启动结构体
stProcInfo        PROCESS_INFORMATION        <>                ;接收进程启动后的信息
szBuffer        db        5 dup (?)                        ;目的地址
dwTemp                dd        ?                                ;接收临里数据
lphMemory        dd        ?                                ;内存句柄
;===========常量定义=====================================
.const
szExecFileName        db        'xyza.exe',0
szErrExec        db        'Sory The File Name is Bad',0
szAppname        db        'Memory',0
szMemoryError        db        'Alloc Memory Failed',0

dbPatched        db        68h,00h,00h,14h,00h                ;要写入目标的内容(push 00140000)

szIP                db        '192.168.1.200',0                ;定义IP地址
;===========代码段=======================================
.code
start:
        invoke        GetStartupInfo,addr stStartUp
        invoke        CreateProcess,offset szExecFileName,NULL,NULL,NULL,NULL,\
                NORMAL_PRIORITY_CLASS or CREATE_SUSPENDED,NULL,NULL,offset stStartUp,offset stProcInfo
                        ;参数说明
                        ;lpApplicationName        要创建的应用程序名
                        ;lpCommandLine                通过命令行获取
                        ;pProcessAttributes        指向一个SECURITY_ATTRIBUTES结构体
                        ;lpThreadAttributes        同上
                        ;bInheritHandles        指示新进程是否从调用进程处继承了句柄
                        ;dwCreationFlags        创建标志
                        ;lpEnvironment                是否需要指向新的环境
                        ;lpCurrentDirectory        指向一个路径
                        ;lpStartupInfo                启动结构体
                        ;lpProcessInformation        接收进程序信息
       
        .if        eax        ;判断eax==1(是否创建成功)
                invoke        VirtualAllocEx,stProcInfo.hProcess,NULL,1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE
                        ;参数说明
                        ;hProcess                要申请内存的目标句柄
                        ;lpAddress                保留页面的内存地址;一般用NULL自动分配
                        ;dwSize                        欲分配的内存大小以字节单位;注意实际分配的内存大小是页内存大小的整数倍
                        ;flAllocationType        分配的内存类型
                        ;flProtect                分配到的内存的功能
                        ;--------------------------------------------

                        .if        eax        ;判断eax==1(是否分配到内存)
                                mov        lphMemory,eax                        ;保存内存句柄
                                lea        eax,szIP
                                mov        lphMemory,eax
                                ;invoke        MessageBox,NULL,lphMemory,offset szAppname,MB_OK
                        .else
                                invoke        MessageBox,NULL,addr szMemoryError,addr szAppname,MB_OK
                        .endif
                invoke        WriteProcessMemory,stProcInfo.hProcess,M_BaseAddress,offset dbPatched,5,offset dwTemp
                        ;参数说明
                        ;hProcess                目标进程的句柄
                        ;lpBaseAddress                要写入目标进程的起始地址Target
                        ;lpBuffer                存放要写入数据的地址
                        ;nSize                        要读取数据的大小
                        ;lpNumberOfBytesRead        实际读取的大小
                        ;--------------------------------------------
                invoke        ResumeThread,stProcInfo.hThread
        .else
                invoke        CloseHandle,stProcInfo.hProcess
                invoke        CloseHandle,stProcInfo.hThread
                invoke        MessageBox,NULL,addr szErrExec,addr szAppname,MB_OK
        .endif
        invoke        ExitProcess,NULL
       
end start

在网上看有人告诉我用VirtualProtect可我不知道为什么,在次,真诚的希望能得到帮助和支持,谢谢,再谢谢
若有会的,可以和我电话联系。

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (19)
雪    币: 421
活跃值: (60)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
我不会,另外,你没有100KX币!
2010-10-5 21:19
0
雪    币: 270
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
真相帝!!!!
2010-10-5 21:21
0
雪    币: 2109
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
http://www.cppblog.com/shaker/archive/2007/08/28/31075.html
"发一个mir2的内挂代码" (C)

"                VirtualProtect((void*)0x44c586,9,PAGE_READWRITE,&dwOldFlag);
                    memcpy((void*)0x44c586,&d,4);
                    memcpy((void*)0x44c58a,bb,5);
                    VirtualProtect((void*)0x44c586,9,dwOldFlag,&dwOldFlag)"

http://www.feiesoft.com/win32asm/win32asm-10-7.html
"Windows 32位汇编语言程序设计教程第10章 内存管理和文件操作"
"除了用VirtualAlloc函数在提交内存的时候指定不同的保护方式外,也可以在以后用VirtualProtect函数来改变虚拟内存页的保护方式。比如,应用程序可以按PAGE_READWRITE来提交一个页并立即将数据写到该页中,然后马上使用VirtualProtect函数将该页的保护方式改为PAGE_READONLY,这样可以有效地保护数据不被该进程中的任何线程重写。"

http://bbs.pediy.com/showthread.php?t=59746
"【原创】createprocess hook dll 执行exe中的函数."

" DWORD fNew, fOld;

  fNew = PAGE_READWRITE;

  VirtualProtect((void*)old_adress_encrypt, sizeof(btOldEncryptBytes), fNew, &fOld);

  WriteProcessMemory(hGame, (void *)old_adress_encrypt, (void *)btNewBytes, sizeof(btOldEncryptBytes), &dwCodeSize);

  VirtualProtect((void*)old_adress_encrypt, sizeof(btOldEncryptBytes), fOld, &fNew);"

http://blog.csdn.net/fun0526/archive/2010/08/03/5785210.aspx
"CreateProcess注入方法"

"# // 修改内存属性  
# DWORD dwNew***, dwOld***;  
# dwNew*** = PAGE_READWRITE;  
# VirtualProtectEx(m_proInfo.hProcess, (LPVOID)pEntryPoint, sizeof(DWORD), dwNew***, &dwOld***);  
# WriteProcessMemory(m_proInfo.hProcess, pEntryPoint, &newCode, sizeof(newCode), NULL);//&dwWrited);  
# VirtualProtectEx(proInfo.hProcess, (LPVOID)pEntryPoint, sizeof(DWORD), dwOld***, &dwNew***);  "
2010-10-6 00:59
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢enthos的热心帮助,我想还是我的问题没有表达清楚
首先函数VirtualProtectEx函数我明白他的意思,就是修改目标进程指定内存页的属性
现在的关键问题不是这些
关键问题是
一、我上面提到的0040E1D2这个地址是在OD里面看到的代码段
    而他上面的语句是
    mov     edx, dword ptr [esp+1C]
      push    edx
它要实际的是给函数inet_addr压入所需参数,由于esp+1C指向的是堆栈段数据
我无法修改为此,我才要编写一个程序来启动这个程序,以达到控制这个程序的目的
那么,问题出来了,你不可能在目标进程中定义常量szIP='192.168.1.1'
只能在自己进程中定义,然后通过在目标进程中临时申请一块内存,再将我上面的常量放进去
此时在修改0040E1D2处的代码push 00140000(0014000是申请到目标进程的地址),这样,目标进程才能访问自己进程内的数据。
而不是只是修改内存属性,再者,修改代码段的属性还是修改数据段的属性呢?这是一问
从上面004E1D2 看得出是代码段地址,要修改这个地方,直接用createprocess与writeProcessMemory来修改就行了,不费事,关键是我们的常量szIP目标进程要能访问
谢谢
2010-10-6 08:41
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢各位的热心帮助,我想还是我的问题没有表达清楚
首先函数VirtualProtectEx函数我明白他的意思,就是修改目标进程指定内存页的属性
现在的关键问题不是这些
关键问题是
一、我上面提到的0040E1D2这个地址是在OD里面看到的代码段
    而他上面的语句是
    mov     edx, dword ptr [esp+1C]
      push    edx
它要实际的是给函数inet_addr压入所需参数,由于esp+1C指向的是堆栈段数据
我无法修改为此,我才要编写一个程序来启动这个程序,以达到控制这个程序的目的
那么,问题出来了,你不可能在目标进程中定义常量szIP='192.168.1.1'
只能在自己进程中定义,然后通过在目标进程中临时申请一块内存,再将我上面的常量放进去
此时在修改0040E1D2处的代码push 00140000(0014000是申请到目标进程的地址),这样,目标进程才能访问自己进程内的数据。
而不是只是修改内存属性,再者,修改代码段的属性还是修改数据段的属性呢?这是一问
从上面004E1D2 看得出是代码段地址,要修改这个地方,直接用createprocess与writeProcessMemory来修改就行了,不费事,关键是我们的常量szIP目标进程要能访问
谢谢
2010-10-6 08:52
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
你自己的程序修改目标进程不成功吗?我觉得应该修改成功了啊?
2010-10-6 09:19
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
8
哥们,我看了你的帖子,觉得你相当蛋疼啊,既然你描述不清楚,就把程序发上来呗,发上来哥给你整一个成品
如果你的程序涉及什么秘密,你可以自己写个类似的发上来
2010-10-6 14:27
0
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
9
楼主写的程序也很蛋疼啊,不知道是故意掩饰什么,还是本身就是一个纯粹的半成品。
虽然你没有100Kx,但还是说说你的代码的错误吧:

  mov  lphMemory,eax      ;保存内存句柄
  lea  eax,szIP
  mov  lphMemory,eax
你这是想搞什么?你的意思是想把本进程中的IP拷到目标进程你申请的内存里吧?老大,好歹你也用memcpy才靠谱。你这个操作,鬼才知道干了什么。而且,进程间你要数据写入,还得使用WriteProcessMemory好不好!
mov  lphMemory,eax      ;保存内存句柄
WriteProcessMemory,stProcInfo.hProcess,lphMemory,offset dbPatched,5,offset dwTemp

  .const
  dbPatched  db  68h,00h,00h,14h,00h    ;要写入目标的内容(push 00140000)
补丁是个硬编码,还是个const。。。
老大,申请到的内存位置不是你说了算的。好歹把它移到.data段,得到lphMemory以后,把你的硬编码改掉好不好!
  .data
  dbPatched db 68h
  dbPatched_IP dd ?
  .code
mov  lphMemory,eax      ;保存内存句柄
mov eax,lphMemory
mov dbPatched_IP,eax

看着有100Kx又得不到,郁闷啊郁闷

另,OD已经告诉你了,这是一个inet_addr,其实你完全可以跳过它。
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
0040E1D6  |.  90            nop                                      ; nop
0040E1D7  |.  66:894424 0A  mov     word ptr [esp+A], ax
0040E1DC  |.  B8 C0A801C8   mov eax,0C801A8C0                        ;192.168.1.200
这样只需要一次修改,无需申请内存。
2010-10-6 17:08
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
10
我来解释下,楼主的100kx已经支付给论坛了,所以现在显示他没有kx了。
只要被采纳,是不愁得不到kx的
2010-10-6 17:34
0
雪    币: 58
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
帮顶,看得眼睛都花了
2010-10-7 01:13
0
雪    币: 58
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
是可以显示图片的。
http://bbs.pediy.com/showpost.php?postid=292659
2010-10-7 01:17
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
进来看看,学习一下。哈哈。
2010-10-7 02:25
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
多谢这位兄弟的热心支持
这么多回答中,你的回答我比较满意,因为我想要的就是你要说的
最后补充一点
不能跳过inet_addr因为程序需要用到它来连服务器
另,一万分的真诚求你的QQ号,或手机号,我想直接问一问,谢谢
2010-10-7 11:12
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
各位朋友,你们好!
我下面的问题走过百度、方过谷哥、踏过众多win32汇编QQ群
同时也在看雪里发过贴子,但问题始终没人能解决。得到的结果如下,一回答不具体,只说其一,不说其二,就好知道什么说什么(当然这也许是出于热心的原帮)
二、回答不够专业(用其他语言来解决,这当然不行,因为我只会win32汇编)
三、都不愿意一直回答下去(可以是太忙了吧)
但最后还是将希望寄托在看雪
我的问题如下:
用OD加载某A程序、运行,且我在0040E1D2处下断(有朋友就问为什么要在那下断)为此我把图给各位看,一看到inet_addr就知道为什么要在那下断了。
0040E1C0  |.  51            push    ecx                              ; /NetShort
0040E1C1  |.  894424 14     mov     dword ptr [esp+14], eax          ; |
0040E1C5  |.  66:C74424 08 >mov     word ptr [esp+8], 2              ; |
0040E1CC  |.  FF15 B4E54300 call    dword ptr [<&WS2_32.#9>]         ; \ntohs
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]0040E1D6  |.  52            push    edx                              ; /pAddr
0040E1D7  |.  66:894424 0A  mov     word ptr [esp+A], ax             ; |
0040E1DC  |.  FF15 B8E54300 call    dword ptr [<&WS2_32.#11>]        ; \inet_addr
从反汇编上看,为了给inet_addr函数压入参数
先是用了一个
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
然后再push edx
现在的问题是
0040E1D2  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
中esp+1C所向的IP地址为192.168.1.200
可以从堆栈窗口中看出,但这个值不符合要求
Stack ss:[0012EBC4]=0012F018, (ASCII "192.168.1.200")
edx=00000038

我需要的是192.168.1.有朋友马上就说,你可以直接在程序的堆栈窗口中修改一下不就行了吗
是的,我们可以动态修改,有朋友还说,你还可以从内存窗口中修改,我的回答是,可以
但这些都不是彻底解决问题的办法
在我认为,最彻底的办法是,如果我能在目标进程一开始的地方(从代码的脚度看)
定义常量的地方,定义这么一个szIP='192.168.1.1'
而上面需要压入的参数直接用push 我们szIP的地址,这不就行了吗,想法很大胆,也很天真,很多高手会笑话我,哪有那么容易,我知道这是不可能的
但是我们也会有办法吗,用一个进程来打开它,控制它,然后在他里面申请一块内存,放入我们上面的值,同时用WriteProcessMemory修改那个位置的代码,这不就行了吗
是的如果能这样做当然行
为此有的朋友就说你用DLL注入啊,用CreateProcess+WriteProcessMemory以及
VirtualProtectEx配合啊。
可是,我要说的是可是
包括我在内的很多朋友都知道这样的思路,但做起来就不一样啊
希望热心的朋友能给出段代码(限win32汇编的代码,其它语言实现起来有可能很简单)
且有解决问题的明确思路
在此,先谢过
我第三次在看雪上发贴,第一次时不知道直接填了100Kx后来才知道后悔了
现在我没有Kx了.........................
难过中
2010-10-7 13:17
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
16
你的描述可能因为你的不恰当,不准确,或者一些你根本没有意识到或者意识不到的问题导致大家不能理解;反之,大家给出的办法可能由于你没有实现好而导致失败。

所以,请你放上程序吧,大家都很想帮助你的
2010-10-7 14:00
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
程序由于特殊的原因不能上传,但希望得到各位朋友的帮助
2010-10-7 20:31
0
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
18
你的描述算清楚了吧。只是好像多了一点,大家懒得看这么多而已啦。
白赚了你100Kx,很不好意思。我再把解决方法说细一点吧。

你说inet_addr不可跳过,怎么不能跳过了,我只是说跳过0040E1DB这里的inet_addr一次调用而已。
其实这样的话,你完全可以不用写程序,直接手术PE就得了。因为看你这个程序代码状态,应该是没有加壳的。所以你只需要找到PE文件里的相对位置,做个patch,可以完全搞定的。

当然,如果你非想用runtime patch不可。以下改过你代码,你试试吧。(很久没写完全的ASM了,而且现在手里也没有编译器,所以也不能保证能成。。。)
.586
.model flat,stdcall
option casemap:none

;====Include文件=================
include include\windows.inc
include include\kernel32.inc
include include\user32.inc

;====Lib文件=====================
includelib lib\kernel32.lib
includelib lib\user32.lib

;===========EQU数据======================================
M_BaseAddress  equ  0040E1D6h  ;要读写的地址(从push edx开始)

;===========已初始化的数据===============================
.data

;===========未初始化的数据===============================
.data?
stStartUp  STARTUPINFO    <>    ;启动结构体
stProcInfo  PROCESS_INFORMATION  <>    ;接收进程启动后的信息
szBuffer  db  5 dup (?)      ;目的地址
dwTemp    dd  ?        ;接收临里数据
lphMemory  dd  ?        ;内存句柄
;===========常量定义=====================================
.const
szExecFileName  db  'xyza.exe',0
szErrExec  db  'Sory The File Name is Bad',0
szAppname  db  'Memory',0
szMemoryError  db  'Alloc Memory Failed',0

dbPatched  db  90h,66h,89h,44h,24h,0Ah,0B8h    ;要写入目标的内容
	dd	0101A8C0h	;192.168.1.1(根据需要改IP地址,注意网络顺序)

szIP    db  '192.168.1.200',0    ;定义IP地址
;===========代码段=======================================
.code
start:
  invoke  GetStartupInfo,addr stStartUp
  invoke  CreateProcess,offset szExecFileName,NULL,NULL,NULL,NULL,\
    NORMAL_PRIORITY_CLASS or CREATE_SUSPENDED,NULL,NULL,offset stStartUp,offset stProcInfo
      ;参数说明
      ;lpApplicationName  要创建的应用程序名
      ;lpCommandLine    通过命令行获取
      ;pProcessAttributes  指向一个SECURITY_ATTRIBUTES结构体
      ;lpThreadAttributes  同上
      ;bInheritHandles  指示新进程是否从调用进程处继承了句柄
      ;dwCreationFlags  创建标志
      ;lpEnvironment    是否需要指向新的环境
      ;lpCurrentDirectory  指向一个路径
      ;lpStartupInfo    启动结构体
      ;lpProcessInformation  接收进程序信息
  
  .if  eax  ;判断eax==1(是否创建成功)
    invoke  WriteProcessMemory,stProcInfo.hProcess,M_BaseAddress,offset dbPatched,11,offset dwTemp
      ;参数说明
      ;hProcess    目标进程的句柄
      ;lpBaseAddress    要写入目标进程的起始地址Target
      ;lpBuffer    存放要写入数据的地址
      ;nSize      要读取数据的大小
      ;lpNumberOfBytesRead  实际读取的大小
      ;--------------------------------------------
    invoke  ResumeThread,stProcInfo.hThread
  .else
    invoke  CloseHandle,stProcInfo.hProcess
    invoke  CloseHandle,stProcInfo.hThread
    invoke  MessageBox,NULL,addr szErrExec,addr szAppname,MB_OK
  .endif
  invoke  ExitProcess,NULL
  
end start
2010-10-8 09:47
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
堅持一種學習也是一種動力
2010-10-11 16:05
0
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
牛人啊,崇拜中。。。
2011-10-12 11:33
0
游客
登录 | 注册 方可回帖
返回
//