浏览http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html
execve我理解了调用并试图重写它的nasm 程序。
一些背景信息:
int execve(const char *filename, char *const argv[], char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
因此,eax = 11( 的函数调用号execve),ebx应该指向char* filename,ecx应该指向argv[](这将与第一个参数相同,ebx因为第一个参数是其*filename本身,例如在本例中为“/bin/sh”),并且edx将指向envp[](null在本例中)。
原始nasm代码:
global _start
section .text
_start:
xor eax, eax
push eax
; PUSH //bin/sh in reverse i.e. hs/nib//
push 0x68732f6e
push 0x69622f2f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, …Run Code Online (Sandbox Code Playgroud) 第一次海报.第二年CS学生.
我正在探索在C源代码 - > GCC编译 - > Linux执行环境的上下文中虚拟地址空间的.data部分中创建静态变量.
C程序是test.c
int main()
{
register int i = 0;
register int sum = 0;
static int staticVar[10] = {1,2,3,4,5,6,7,8,9,-1};
Loop:
sum = sum + staticVar[i]; //optimized away
i = i+1;
if(i != 10)
goto Loop;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要求GDB' disass /m'显示staticVar []创建没有代码,因为检查.s文件会显示变量驻留在创建进程时放置在那里的虚拟地址空间的读/写.data段中(这个过程是我感兴趣的).
检查(我虽然它是' readelf -A test.o')的输出,目标文件包含我假设在数据段中创建数组的程序集.这是ELF输出.
(如果你可以告诉我什么命令生成这个输出,我可以使用readelf来复制它.我从网站上获取命令并保存输出.我不记得是如何生成的)
[剪断]
00000000 <staticVar.1359>:
0:01 00 add %eax,(%eax)
2:00 00 add %al,(%eax)
4:02 00 add (%eax),%al
6:00 00 add %al,(%eax)
8:03 00 add (%eax),%eax …Run Code Online (Sandbox Code Playgroud) 我需要看一个具体的例子,说明如何在 ac 程序中为 execve() 指定环境。在我的课堂上,我们正在编写一个程序,该程序将使用标准的 LINUX 可执行文件和我们自己的可执行文件。因此,环境搜索 PATH 必须包含两种类型的可执行文件的标记。我找不到一个很好的例子来说明如何为 execve() 指定环境(第三个参数),因为每篇文章似乎都建议我们改用 execvp() 或 *clp() 或 *cl() 等。
在我的项目中,我们必须使用execve()。
现在,我只是想让 execve() 为一个基本的“ls”命令工作,以便我可以让它在以后为任何和所有可执行文件工作。
这是我的实验代码片段:
else if(strcmp(tokens[0], "1") == 0) {
char *args[] = {"ls", "-l", "-a", (char *)0};
char *env_args[] = {"/bin", (char*)0};
execve(args[0], args, env_args);
printf("ERROR\n");
}
Run Code Online (Sandbox Code Playgroud)
每次在我的 shell 中输入命令“1”时,我都会看到我的错误消息。我怀疑这是因为我声明 env_args[] 的方式。
有人可以向我展示如何使用指定的命令搜索环境实现 execve() 的好例子吗?
我必须填写以下参数:
int execve(const char *filename, char *const argv[], char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
如果我执行这个程序:
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/sh";
args[1] = NULL;
execve(args[0], args, NULL);
}
Run Code Online (Sandbox Code Playgroud)
shell 按预期正确生成。
我的问题是,如果我传递 NULL 作为第二个参数,shell 也会正确生成:
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/sh";
args[1] = NULL;
execve(args[0], NULL, NULL);
}
Run Code Online (Sandbox Code Playgroud)
那么使用 args 向量(带有“/bin/sh”+ NULL)作为第二个参数而不是 NULL 的目的是什么?
是否可以从 launchd 守护进程使用execve ?我想将进程制作成守护进程,然后使用 fork() 和 execve 启动多个子进程,但创建 launchd 守护进程的文档指出“调用 fork 后跟 exec”是不行的。这是否意味着我无法从守护进程创建子进程?
我想从我的代码中执行一个程序,并为它提供环境变量和参数.AFAICT,execve是正确的选择.
但是,execve接收一个path参数,而不是一个filename,意味着它期望第一个参数是可执行文件的路径.
我知道我可以解析$PATH自己寻找路径,但实际上,没有别的选择吗?没有其他人在某处实现它供我使用吗?
我想看看我在execve()函数中传递的环境变量是否真的被传递了,所以我编写了以下代码(Main.c):
int main(){
char PATH[4];
strcpy(PATH, "bin");
char * newargv[] = {"./get","", (char*)0};
char * newenviron[] = {PATH};
execve("./get", newargv, newenviron);
perror("execve");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(get.c):
int main()
{
const char* s = getenv("PATH");
printf("PATH :%s\n",s);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我执行Main.c发行的二进制文件时,得到以下输出:
路径:(空)
而我想看看
路径:bin
你有什么解释吗?
我试图使用execve来运行ls命令.目前我正在使用以下参数运行它:
execve(args[0], args, env_args)
//args looks like {"ls", "-l", "-a", NULL}
//env_args looks like {"PATH=/bin", "USER=me", NULL}
Run Code Online (Sandbox Code Playgroud)
我期望这样做是使用我的新env_args运行ls命令,这意味着它将在我的PATH中查找ls.但是,这段代码实际上没有做任何事情,当我运行代码时它只返回我的命令提示符而没有输出.
使用相同的args []我使用execvp并且ls工作并搜索我当前的路径.
你能告诉我我做错了什么吗?
我想要做的是编写我自己的shell程序,在那里我可以创建和导出我自己的环境,并让exec使用我在char**中定义的环境.本质上我正在编写自己的函数来操作env_args来添加和删除变量,当我调用exec时我希望能够在{"ls"," - l",NULL}上调用exec并让它看不起我的新环境名为ls的有效程序的路径变量.我希望这能解释我的工作做得更好.在这种情况下,我不认为extern environ var对我有用.
execve()究竟做了什么?我已经尝试过查看文档(http://linux.die.net/man/2/execve),但鉴于我对linux很新,这种编程方式并没有多大意义.我想要做的是能够执行此命令:
nc -l -p someport -e /bin/sh
Run Code Online (Sandbox Code Playgroud)
我可以做类似以下的事情(其中someport是一个数字,如4444)
char *command[2];
command[0] = "nc -l -p someport -e /bin/sh"
execve(command[0], name, NULL);
Run Code Online (Sandbox Code Playgroud) 我想编写一对程序,其中一个程序读取数据并将其传输到内部格式,另一个程序将内部格式转换为其他程序.作为一个练习,我想在不使用管道的情况下编写这些程序之间的交互.我更喜欢使用信号和共享内存.
我有程序A和B,其中A调用B.我怎么能
更具体地说,A解码自定义视频格式并将单个未压缩帧放入共享缓冲区.B从缓冲区读取并将其编码为输出strean.解码器每秒最多解码100帧,大约500 MiB/s内存流量.由于数据必须经常复制并且缓冲区不是很大,所以管道结果很慢.
我的想法是用来mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0)创建一部分共享内存.问题是,execve(2)国家的联合页面:
不保留内存映射(mmap(2)).
那么,我如何与其他程序共享该内存?将两种功能集成到一个程序中并使用它是一个更好的主意fork吗?