其中一些代码可能对这是如何发生的以及为什么产生了任何意义(甚至让我感到困惑)。 这段代码旨在用于其他目的(我正试图制作一个计算器,所以主要的源代码[几乎没有问题]作为我的问题存在于此站点上)我以某种方式破坏了它,因此我对其进行了修改并提取了代码最初破坏了它。
我在Kali Linux上进行了测试。
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
//Some of this might not make any sense, but its the way i was able to break it.. somehow
int main(int argc,char *argv[]) {
FILE *file = fopen(argv[2],"a");
if(file == NULL) {
printf("Error Opening File!");
return 1;
}
char ch;
int i;
printf("%i\n",argc);
printf("%i\n",argv);
while((ch = getopt(argc,argv,"d:"))!=EOF)
switch(ch) {
case 'd':
for(i=4; i<=48; i++) // This loop may vary on other system. On first run i used "i<=51" , and on different system, same os, its the mentioned condition
fprintf(file,"%s \n",argv[i]);
fclose(file);
break;
default:
fprintf(stderr,"No such command");
}
argc-=1;
argv+=1;
return 0;
}
运行时产生以下结果(原始源代码。此代码会将其写入文件):
argv =的值 LS_COLORS = rs = 0:di = 01; 34:ln = 01; 36:mh = 00:pi = 40; 33:so = 01; 35:do = 01; 35:bd = 40; 33; 01:cd = 40; 33; 01:or = 40; 31; 01:mi = 00:su = 37; 41:sg = 30; 43:ca = 30; 41:tw = 30; 42:ow = 34; 42:st = 37; 44:ex = 01; 32: .tar = 01; 31: .tgz = 01; 31: .arc = 01; 31: .arj = 01; 31: .taz = 01; 31: .lha = 01; 31: .lz4 = 01; 31: .lzh = 01; 31: .lzma = 01; 31: .tlz = 01; 31: .txz = 01; 31: .tzo = 01; 31: .t7z = 01; 31: .zip = 01; 31: .z = 01; 31: .Z = 01; 31: .dz = 01; 31: .gz = 01; 31:< em> .lrz = 01; 31: .lz = 01; 31: .lzo = 01; 31: .xz = 01; 31: .zst = 01; 31 : .tzst = 01; 31: .bz2 = 01; 31: .bz = 01; 31: .tbz = 01; 31: .tbz2 = 01; 31: .tz = 01; 31: .deb = 01; 31: .rpm = 01; 31: .jar = 01; 31:。 war = 01; 31: .ear = 01; 31: .sar = 01; 31: .rar = 01; 31: .alz = 01; 31: .ace = 01; 31: .zoo = 01; 31: .cpio = 01; 31: .7z = 01; 31: .rz = 01; 31 : .cab = 01; 31: .wim = 01; 31: .swm = 01; 31: .dwm = 01; 31: .esd = 01 ; 31: .jpg = 01; 35: .jpeg = 01; 35: .mjpg = 01; 35: .mjpeg = 01; 35:。 gif = 01; 35: .bmp = 01; 35: .pbm = 01 ; 35: .pgm = 01; 35: .ppm = 01; 35: .tga = 01; 35: .xbm = 01; 35: .xpm = 01; 35: .tif = 01; 35: .tiff = 01; 35: .png = 01; 35: .svg = 01; 35: .svgz = 01; 35: .mng = 01; 35: .pcx = 01; 35: .mov = 01; 35: .mpg = 01; 35: .mpeg = 01; 35: .m2v = 01; 35: .mkv = 01; 35: .webm = 01; 35: .ogm = 01; 35: .mp4 = 01; 35: .m4v = 01; 35: .mp4v = 01; 35: .vob = 01; 35: .qt = 01; 35: .nuv = 01; 35: .wmv = 01; 35: .asf = 01; 35: .rm = 01; 35: .rmvb = 01; 35: .flc = 01; 35: .avi = 01; 35: .fli = 01; 35: .flv = 01; 35:< /em>.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01; 35: .cgm = 01; 35: .emf = 01; 35: .ogv = 01; 35: .ogx = 01; 35: .aac = 00; 36: .au = 00; 36: .flac = 00; 36: .m4a = 00; 36: .mid = 00; 36: .midi = 00; 36: .mka = 00; 36: .mp3 = 00; 36: .mpc = 00; 36: .ogg = 00; 36:< em> .ra = 00; 36: .wav = 00; 36: .oga = 00; 36: .opus = 00; 36: .spx = 00; 36 : .xspf = 00; 36:
argv = XDG_MENU_PREFIX = gnome-的值
argv = LANG = en_IN的值
argv = GDM_LANG = en_IN上的值
argv = MANAGERPID = 793的值
argv = DISPLAY =:1处的值
argv = INVOCATION_ID = 3e7f771adfde4001af637f9527e9cc9d的值
argv = COLORTERM = truecolor的值
argv = USERNAME = root的值
argv = XDG_VTNR = 2的值
argv = SSH_AUTH_SOCK = / run / user / 0 / keyring / ssh的值
argv = S_COLORS = auto的值
argv = XDG_SESSION_ID = 3的值
argv = USER = root的值
argv = DESKTOP_SESSION = gnome的值
argv = PWD = / media / root / F89AF7139AF6CCDE的值
argv = HOME = / root的值
argv = Journal_STREAM = 9:19456的值
argv = SSH_AGENT_PID = 945的值
argv = QT_ACCESSIBILITY = 1的值
argv = XDG_SESSION_TYPE = x11的值
argv =的值 XDG_DATA_DIRS = / usr / share / gnome:/ usr / local / share /:/ usr / share /
argv = XDG_SESSION_DESKTOP = gnome的值
argv =的值 DBUS_STARTER_ADDRESS = unix:path = / run / user / 0 / bus,guid = 11c587e1337f9fb06858c2415bbac73a
argv = GTK_MODULES = gail:atk-bridge的值
argv = WINDOWPATH = 2处的值
argv = TERM = xterm-256color处的值
argv = SHELL = / bin / bash处的值
argv = VTE_VERSION = 5002的值
argv = DBUS_STARTER_BUS_TYPE = session上的值
argv = XDG_CURRENT_DESKTOP = GNOME的值
argv = GPG_AGENT_INFO = / run / user / 0 / gnupg / S.gpg-agent:0:1处的值
argv = SHLVL = 1处的值
argv = XDG_SEAT = seat0的值
argv = LANGUAGE = en_IN:zh_cn的值
argv = WINDOWID = 39845894的值
argv = GDMSESSION = gnome的值
argv = GNOME_DESKTOP_SESSION_ID =已弃用的值
argv = LOGNAME = root的值
argv =的值 DBUS_SESSION_BUS_ADDRESS = unix:path = / run / user / 0 / bus,guid = 11c587e1337f9fb06858c2415bbac73a
argv = XDG_RUNTIME_DIR = / run / user / 0的值
argv = XAUTHORITY = / run / user / 0 / gdm / Xauthority的值
argv =的值 PATH = / usr / local / sbin:/ usr / local / bin:/ usr / sbin:/ usr / bin:/ sbin:/ bin
argv =的值 SESSION_MANAGER =本地/ kali:@ / tmp / .ICE-unix / 894,unix / kali:/tmp/.ICE-unix/894
argv = _ =。/ a.out的值
argv =(空)的值
接下来的问题是,环境变量实际上是什么?为什么我给我这样的结果?
// probably use one option at a time
//This code has some flaws, for example i didnt check if the file was opened
or not, etc, pardon me for it. This is the actual un-edited source of the
code.
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int add(int a,int b){
return a+b;
}
int subtract(int a, int b){
return a-b;
}
int main(int argc, char *argv[]){
FILE *file1 = fopen("Results.txt","a");
char ch;
int res;
while((ch=getopt(argc,argv,"a:s:"))!=EOF)
switch (ch){
case 'a':
res = add(atoi(optarg),atoi(argv[3]));
fprintf(file1,"%i\n",res);
break;
case 's':
res = subtract(atoi(optarg),atoi(argv[3]));
printf("%i \n",res);
fprintf(file1,"%i\n",res);
break;
default:
fprintf(stderr,"No such option");
return 1;
}
//THe commented out section produces weird behaviour...
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
argc-=optind;
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[3]);
argv+=optind;
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[1]);
fprintf(file1,"\nWritten to file\n");
fclose(file1);
return 0;
}
答案 0 :(得分:1)
首先,超出数组范围将导致undefined behavior。当您遍历argv
数组而不检查例如i < argc
(除非您实际上在命令行上提供了48个以上的参数)。
第二,关于为什么在超出argv
的范围时打印环境变量的原因,这是因为在POSIX系统(例如Linux或macOS)上,{ {1}}函数,通常称为main
。与environ
类似,它是一个包含环境变量的字符串数组(以相同的方式声明,例如argv
)。通过超出char *environ[]
的边界,您将进入argv
数组的内存。
在相关说明中,您使用environ
时没有检查该参数是否实际存在,或者没有使用argv[2]
解析的其他任何参数。不要那样做。
还请注意,getopt
函数将返回 getopt
。对于检查int
(而不是-1
!),这实际上非常重要和重要。