Closed. This question needs details or clarity。它当前不接受答案。
想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
2年前关闭。
我想真正的目标是成功模仿strace的输出,以神奇地输出的
并使其尽可能清楚:
这意味着它将以控制台不会解释的方式显示它们。例如,如果文件包含\ 0004或\ 0104,那么它将以文字字符串显示\ 0004和\ 0104(就像您写的是\\ 0004或\\ 0104一样),因此控制台将不会对其进行解释。
以下是其外观的示例(除了
当使用
是的,很明显,在第一种情况下,对
想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
2年前关闭。
我想真正的目标是成功模仿strace的输出,以神奇地输出的
read()
syscall参数读取。并使其尽可能清楚:
这意味着它将以控制台不会解释的方式显示它们。例如,如果文件包含\ 0004或\ 0104,那么它将以文字字符串显示\ 0004和\ 0104(就像您写的是\\ 0004或\\ 0104一样),因此控制台将不会对其进行解释。
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char * argv[]) {
#include <stdio.h>
int shift(int times) {
#ifdef SHIFT_VERBOSE
int shift_mode_verbose = 1;
#else
int shift_mode_verbose = 0;
#endif
if (shift_mode_verbose == 1) {
printf("The following arguments were passed (before) to main(%i):\n", argc);
for(int i=1; i<argc; i++) {
printf("arg%i: %s\n", i, argv[i]);
}
printf("\n");
}
if (shift_mode_verbose == 1) {printf("shifting %i times\n", times);}
for(int t=1; t<times+1; ++t) { // we set this to 1 and respectively increase by 1, to avoid shifting argv[0] as it is holds the program name
for(int i=1; i<argc; ++i) { // we set this to 1 to avoid shifting argv[0] as it is holds the program name
if (shift_mode_verbose == 1) {printf("shift %i: arg%i: %s >", t, i, argv[i]);}
argv[i] = argv[i+1];
if (shift_mode_verbose == 1) {printf(" %s\n", argv[i]);}
}
--argc;
}
if (shift_mode_verbose == 1) {
printf("The following arguments were passed (after) to main(%i):\n", argc);
for(int i=1; i<argc; i++) {
printf("arg%i: %s\n", i, argv[i]);
}
printf("\n");
}
return 0;
}
int fshift(int times) { // a potentially faster version of shift()
times = argc < times ? argc : times;
argc = (argc) - times;
(argv) += times;
return 0;
}
if (argc < 3) {
printf("Usage: %s lines (-1 = all lines), files\n", argv[0]);
return 1;
}
int LINES_TO_READ = atoi(argv[1]);
shift(1);
for (ssize_t i = 1; i < argc; i++) {
const char *filename = argv[i];
printf("printing \"%s\"\n\n", filename);
int fd = open(filename, O_RDONLY);
if (fd < 0) {
printf("cannot open \"%s\", returned %i\n", filename, fd);
return -1;
}
char unsigned ch;
size_t lines = 1;
// Read the file byte by byte
while (read(fd, &ch, 1) == 1) {
if (ch == '\n') {
printf("\\n");
} else if (ch == '\0') {
printf("\\0");
} else if (ch == '\r') {
printf("\\r");
} else if (ch == '\t') {
printf("\\t");
} else if(isprint(ch)) {
printf("%c", ch);
} else {
printf("\\%03o", ch);
}
// FILE *file = fopen(filename, "rb");
// char unsigned ch;
// size_t lines = 1, bytes=1;
// // Read the file byte by byte
// while (fread(&ch, 1, 1, file) == 1) {
// if (ch == '\n') {
// printf("\\n");
// } else if (ch == '\0') {
// printf("\\0");
// } else if (ch == '\r') {
// printf("\\r");
// } else if (ch == '\t') {
// printf("\\t");
// } else if(isprint(ch)) {
// printf("%c", ch);
// } else {
// printf("\\%03o", ch);
// }
if (ch == '\n') {
// Stop if we read 10 lines already
if (lines == LINES_TO_READ) {
break;
}
lines++;
}
}
if (close(fd) < 0) {
printf("cannot close \"%s\"\n", filename);
return -1;
}
printf("\n");
}
return 0;
}
以下是其外观的示例(除了
./catraw
的输出不正确之外)。 (从nasm
,strace
和c at
获取ELF标头和指令。)elf_header='\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0T\200\4\0104\0\0\0\0\0\0\0\0\0\0\0004\0 \0\1\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0\200\4\10\0\200\4\10T\0\0\0T\0\0\0\5\0\0\0\0\20\0\0'
instructions='\263*f1\300f@\315\200'
printf "$elf_header$instructions" > return_42
chmod +x return_42
./return_42 # test run to see if it actually works
echo $? # echo return code of ./return_42
strace -s 4096 cat ./return_42
gcc catraw.c --static -o catraw
strace ./catraw -1 ./return_42
./catraw -1 ./return_42
[PROGRAM ] \177ELF\001\001\001\0\0\0\0\0\0\0\0\0\002\0\003\0\001\0\0\0T\200\004\0104\0\0\0\0\0\0\0\0\0\0\04\0 \0\001\0\0\0\0\0\0\0\001\0\0\0\0\0\0\0\0\200\004\010\0\200\004\010T\0\0\0T\0\0\0\005\0\0\0\0\020\0\0\263*f1\300f@\315\200
最佳答案
这有点不清楚(不确定所有程序集),但是类似这样:
#include <ctype.h>
// Format the character 'c' (which should be cast from char) into a
// string. Will use backslash-escaped form for non-printables.
void tostring(char *buf, size_t buf_max, unsigned int c)
{
if(isprint(c))
{
snprintf(buf, buf_max, "%c", c);
}
else
{
snprintf(buf, buf_max, "\\%3o", c);
}
}
当使用
"\177"
调用时,将构建c = 0177
。是的,很明显,在第一种情况下,对
snprintf()
的调用可以排除在可打印内容之外。08-06 19:57