首页
社区
课程
招聘
[旧帖] [求助]啦啦啦 内存越界啦。。。 期待看雪的大虾出现帮小妹看看。。 0.00雪花
发表于: 2010-3-2 09:38 1631

[旧帖] [求助]啦啦啦 内存越界啦。。。 期待看雪的大虾出现帮小妹看看。。 0.00雪花

2010-3-2 09:38
1631
test.c代码
#include "stdio.h"

int __cdecl main(int __argc,char** __argv, char** __environ){
	
	__asm{
		mov ecx, __argc;
		xor ebx,ebx
		lpush:
			mov eax, __argv[ebx*4]
			mov eax,[eax]
			push eax
			inc ebx
			loop lpush
	}
	printf("argument count:%d, arguments:%s %s",__argc);
	return 0;
}


运行的时候  我是用 test abc来运行的  但是没有读到abc参数。。

内存访问也越界了 不能read 应该是读到__argv缓冲区后面去了 但是那个地址空间没有被分配物理页

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我自己想到问题原因啦

printf后面 c编译器生成的堆栈平衡不对  调用printf之后  
__asm
{
  add esp,8
}

就ok了  

可是现在还有一个问题 就是我输入 test.exe abc  读到的不是 test.exe abc  你们可以试试 - -#
2010-3-2 09:47
0
雪    币: 146
活跃值: (1395)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
我也没看明白
2010-3-2 10:27
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
就是循环把main第二个参数__argv字符串指针数组依次入栈

然后printf呀   printf里面有三个格式符  却只传了一个__argc 这样就可以打出来我刚才循环入栈的__argv字符串了呀  
2010-3-2 10:37
0
雪    币: 364
活跃值: (91)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
好晕啊 我太菜了 呵呵 MAIN第一参数仅仅是参数个数啊 不能打出第二参数中的字符来啊??没看懂啊。要打出字符就直接输出__argv了,入栈也没看你出栈啊、也没见有什么栈操作啊?
2010-3-2 10:54
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
等待看雪坛子里的大虾出现
你们小虾就别回答了
2010-3-2 10:58
0
雪    币: 1787
活跃值: (340)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
试试我这个
#include "stdio.h"

int  main(int __argc,char** __argv, char** __environ){

	char * str1 = "argument count:%d\n";
	char * str2="arguments:%s\n";
	int i =0;
	__asm
	{
		//显示参数个数
		mov eax,__argc
		push eax
		mov eax,str1
		push  eax
		call dword ptr [printf]
		//平衡堆栈
		pop ebx
		pop ebx

		//显示命令行参数
		mov eax,0;
		mov i,eax
lpush:
		//获取参数
		mov         eax,dword ptr [i] 
		mov         ecx,dword ptr [__argv] 
		mov         edx,dword ptr [ecx+eax*4] 
		push        edx  
		mov         eax,dword ptr [str2] 
		push        eax  
		call        dword ptr [printf ]
		//平衡堆栈
		add         esp,8

		//循环判断
		mov         eax,dword ptr [i] 
		add         eax,1 
		mov         dword ptr [i],eax 
		mov         eax,dword ptr [i] 
		cmp         eax,dword ptr [__argc] 
		JL         lpush 
	}
	
	return 0;
}
2010-3-2 14:00
0
雪    币: 119
活跃值: (10)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
8
被二维数组搞的晕的,绕了半天

#include "stdio.h"
#include "string.h"

/*
__argc: 参数个数,最少一个,为程序存放路径,在__argv[0]中
__argv: 存放着所有的参数
__environ: 存放着环境变量
*/

/*
照如下方法,参数的显示顺序是逆序的,
想让显示顺序为顺序,把进栈顺序逆序调整为逆序就可以了,很简单,这里就不写了
*/

int __cdecl main(int __argc, char** __argv, char** __environ)
{
char formatStr[100];
int i;

memset(formatStr, 0, 100);
strcpy(formatStr, "argument count:%d\narguments:");

// “\”虽然在输出时是转义字符,这里只是字符串的拷贝
for(i = 0; i != __argc; i++)
strcat(formatStr, "%s\n");


printf("Code begin from here!\n");
__asm
{

mov ecx, __argc;
xor ebx,ebx

lpush:

/*
这是个二维数组
原来是:
mov eax, __argv[ebx*4]
mov eax, [eax]
这样得到的是:argv[0]和__environ[0](紧接着**argv放置的另一个char**指针)
*/
// 改为:
mov eax, __argv
mov eax, [eax + ebx*4]

push eax
inc ebx
loop lpush



/*
//另法1:
把参数个数的传递也用汇编实现:push __argc, 并调用“printf(formatStr);”也可以
(注意最后的平衡堆栈多加4)


//法2:
//或者这样,连printf函数也包含进来(同时对这两个push进行了平衡堆栈)
push __argc
lea eax, formatStr
push eax
call printf
add esp, 8
*/
}

printf(formatStr, __argc);


// 保持堆栈平衡
__asm
{
xor eax, eax
mov eax, 4
mul __argc

add esp, eax
}

return 0;

}
2010-3-2 23:03
0
雪    币: 31
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我也不会。还是问问别人吧
2010-3-2 23:46
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
好吧,我承认,我是被小妹这两个字骗进来的……
建议这位小妹仔细看一下__argv这个参数,这是(char **)类型的,所以你的
lpush:
      mov eax, __argv[ebx*4]
      mov eax,[eax]

这里是错误的,应该是
lpush:
      mov eax,[__argv]
      mov eax,[eax+ebx*4]

不过这个读出来的是倒着的,例如参数是abc的话,读出来的就是abc D:\arg.exe,而不是D:\arg.exe abc,至于平衡堆栈,你自己也知道了,printf后编译器会加上add esp,8,这明显不够,你自己还要add esp,8一次。
2010-3-3 08:19
0
游客
登录 | 注册 方可回帖
返回
//