IDA使用-2023CICSN华中赛区pwn题逆向为例

文章目录

  • 相关字节标识
  • 导入函数和导出函数
  • 找程序入口函数
  • 选项设置
  • 重命名
  • CISCN2023华中赛区分区赛AWD
    • IDA源码
      • main
  • 构造结构体
      • sub_141B()
    • 打开局部变量类型的视图
    • 增加变量类型
    • 重新定义变量类型
    • 再次设置变量类型并重新定义
    • 再次设置变量类型并重新定义
    • 再次设置变量类型并重新定义
  • 设置函数名
  • 标记已经分析完
  • 找到引用函数的各个地方
  • 对变量重新定义变量类型
  • 转换为字符
  • 格式化字符串"\x1B[36mmybash:%s$ \x1B[0m"
      • sub_25D5()
  • -1转换与相关变量与函数命名
  • 设置sub_25D5()
      • sub_247F(char *a1)
  • 设置sub_247F(char *a1)函数
      • sub_23CA(const char **a1)
  • 设置sub_23CA(const char **a1)函数
      • sub_1523()
  • 设置sub_1523()函数
  • h更换数据形式
  • 更改各个函数名
      • __int64 __fastcall command_touch(__int64 a1)
  • 修改后的__int64 __fastcall command_touch(__int64 a1)
      • __int64 __fastcall command_mkdir(__int64 a1)
  • 修改后的__int64 __fastcall command_mkdir(const char **args)
  • 此时发现void sub_13C8()函数又跳转
  • 注意
  • 修改后的__int64 __fastcall command_cat(const char **args)
  • 修改后的__int64 __fastcall command_rm(const char **args)
  • 修改后的__int64 __fastcall command_echo(char **args)
  • 修改后的__int64 __fastcall command_cd(char **arg)

2023华中pwn题逆向参考视频教程

相关字节标识

_WORD(1个字=2个字节=16位)
_DWORD(2个字=4个字节=32位)
_QWORD(4个字=8个字节=64位)
_OWORD(8个字=16个字节=128位

DB (Define Byte): 用于定义单字节(8位)的数据。
DW (Define Word): 用于定义字(Word)大小的数据,通常为2字节(16位)。
DD (Define Doubleword): 用于定义双字(Doubleword)大小的数据,通常为4字节(32位)。
DQ (Define Quadword): 用于定义四字(Quadword)大小的数据,通常为8字节(64位)。

导入函数和导出函数

在C语言中,导入函数和导出函数是实现模块化编程的关键技术,它们分别用于在不同模块之间共享和使用函数。以下是具体分析:

  • 导出函数:在C语言中,当一个函数被声明为导出时,它意味着这个函数可以在其他模块中被调用。这通常通过特定的编译器指令或关键字来实现,例如在Windows平台的C/C++中使用__declspec(dllexport)来导出DLL中的函数。

在这里插入图片描述

  • 导入函数:与导出函数相对应,导入函数是指在当前模块中引用外部模块定义的函数。在C语言中,导入函数通常涉及到包含相应的头文件,并且确保链接时包含了定义这些函数的目标文件或库文件。

在这里插入图片描述

找程序入口函数

export找到start,start中找到main
在这里插入图片描述

选项设置

在这里插入图片描述

重命名

在这里插入图片描述

CISCN2023华中赛区分区赛AWD

IDA源码

main

__int64 __fastcall main(int a1, char **a2, char **a3)
{int v4; // [rsp+Ch] [rbp-14h]void *ptr; // [rsp+10h] [rbp-10h]void *v6; // [rsp+18h] [rbp-8h]setvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);setvbuf(stderr, 0LL, 2, 0LL);alarm(0x20u);qword_50E0 = sub_141B();*(_DWORD *)qword_50E0 = 0;qword_5150 = qword_50E0;*(_BYTE *)(qword_50E0 + 4) = 47;strncpy(dest, (const char *)(qword_50E0 + 4), 1uLL);do{printf("\x1B[36mmybash:%s$ \x1B[0m", dest);ptr = (void *)sub_25D5();v6 = (void *)sub_247F(ptr);v4 = sub_23CA(v6);free(ptr);free(v6);}while ( v4 );return 0LL;
}

构造结构体

sub_141B()

该函数对建立的堆的不同位置进行变量设置,为了更方便的查看设置的位置,可以设置一个结构体来替代

_QWORD *sub_141B()
{_QWORD *v1; // [rsp+8h] [rbp-8h]v1 = malloc(0x40uLL);if ( !v1 )_exit(0);memset((char *)v1 + 4, 0, 0x10uLL);v1[7] = 0LL;v1[5] = 0LL;v1[4] = 0LL;v1[6] = 0LL;return v1;
}

打开局部变量类型的视图

在这里插入图片描述
在这里插入图片描述

增加变量类型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重新定义变量类型

在这里插入图片描述
在这里插入图片描述
然后代码变为

SomeStruct *sub_141B()
{SomeStruct *v1; // [rsp+8h] [rbp-8h]v1 = (SomeStruct *)malloc(0x40uLL);if ( !v1 )_exit(0);memset(&v1->gap[4], 0, 0x10uLL);*(_QWORD *)&v1->gap[56] = 0LL;*(_QWORD *)&v1->gap[40] = 0LL;*(_QWORD *)&v1->gap[32] = 0LL;*(_QWORD *)&v1->gap[48] = 0LL;return v1;
}
发现在距离起始四个字节后的十六个字节都设置为0memset(&v1->gap[4], 0, 0x10uLL);

memset函数

memset函数是C语言标准库中的一个用于内存操作的函数,它主要用于将某一块内存空间的内容设置为指定的值。

memset函数的原型为:

void *memset(void *s, int c, size_t n);
  • void *s:指向要填充的内存块的指针。
  • int c:需要设置的值,该值会被转换为无符号字符后用来设置内存块。
  • size_t n:要设置的内存块的字节数。

再次设置变量类型并重新定义

在这里插入图片描述
在这里插入图片描述
结果代码

SomeStruct *sub_141B()
{SomeStruct *v1; // [rsp+8h] [rbp-8h]v1 = (SomeStruct *)malloc(0x40uLL);if ( !v1 )_exit(0);memset(v1->some_array, 0, sizeof(v1->some_array));*(_QWORD *)&v1->gap[36] = 0LL;*(_QWORD *)&v1->gap[20] = 0LL;*(_QWORD *)&v1->gap[12] = 0LL;*(_QWORD *)&v1->gap[28] = 0LL;return v1;
}

再次设置变量类型并重新定义

在这里插入图片描述

SomeStruct *sub_141B()
{SomeStruct *v1; // [rsp+8h] [rbp-8h]v1 = (SomeStruct *)malloc(0x40uLL);if ( !v1 )_exit(0);memset(v1->some_array, 0, sizeof(v1->some_array));*(_QWORD *)&v1->gap[24] = 0LL;*(_QWORD *)&v1->gap[8] = 0LL;*(_QWORD *)v1->gap = 0LL;*(_QWORD *)&v1->gap[16] = 0LL;return v1;
}

再次设置变量类型并重新定义

在这里插入图片描述

SomeStruct *sub_141B()
{SomeStruct *v1; // [rsp+8h] [rbp-8h]v1 = (SomeStruct *)malloc(0x40uLL);if ( !v1 )_exit(0);memset(v1->some_array, 0, sizeof(v1->some_array));v1->ptr56 = 0LL;v1->ptr40 = 0LL;v1->ptr32 = 0LL;v1->ptr48 = 0LL;return v1;
}

设置函数名

在这里插入图片描述

标记已经分析完

在这里插入图片描述

找到引用函数的各个地方

在这里插入图片描述
在这里插入图片描述

对变量重新定义变量类型

在这里插入图片描述

__int64 __fastcall main(int a1, char **a2, char **a3)
{int v4; // [rsp+Ch] [rbp-14h]void *ptr; // [rsp+10h] [rbp-10h]void *v6; // [rsp+18h] [rbp-8h]setvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);setvbuf(stderr, 0LL, 2, 0LL);alarm(0x20u);qword_50E0 = SomeStruct::CreateInstance();qword_50E0->unkown_0 = 0;qword_5150 = qword_50E0;qword_50E0->some_array[0] = 47;strncpy(dest, qword_50E0->some_array, 1uLL);do{printf("\x1B[36mmybash:%s$ \x1B[0m", dest);ptr = (void *)sub_25D5();v6 = (void *)sub_247F(ptr);v4 = sub_23CA(v6);free(ptr);free(v6);}while ( v4 );return 0LL;
}

转换为字符

在这里插入图片描述

格式化字符串"\x1B[36mmybash:%s$ \x1B[0m"

字符串 “\x1B[36mmybash:%s$ \x1B[0m” 是一个包含ANSI转义序列的字符串,用于在终端上显示颜色文本。在这个字符串中:

\x1B[36m 是一个ANSI转义序列,用于将随后的文本颜色设置为青色(Cyan)。\x1B 是ESC字符的十六进制表示,[ 表示转义序列的开始,36 是选择青色的颜色代码,而 m 表示结束这个颜色设置。
mybash:%s$ 是实际要显示的文本,其中 %s 可能是一个占位符,用于格式化字符串时替换为某个特定的值。
\x1B[0m 是另一个ANSI转义序列,用于重置文本颜色到默认设置。这里 0 表示默认颜色,而 m 同样表示结束这个设置。

sub_25D5()

_BYTE *sub_25D5()
{int v1; // [rsp+Ch] [rbp-14h]int v2; // [rsp+10h] [rbp-10h]int v3; // [rsp+14h] [rbp-Ch]_BYTE *ptr; // [rsp+18h] [rbp-8h]v1 = 528;v2 = 0;ptr = malloc(0x210uLL);if ( !ptr )_exit(0);while ( 1 ){v3 = getchar();if ( v3 == -1 || v3 == 10 )break;ptr[v2++] = v3;if ( v2 >= v1 && v1 <= 2147483639 ){v1 += 496;ptr = realloc(ptr, v1);if ( !ptr ){fwrite("mybash: allocation error\n", 1uLL, 0x19uLL, stderr);exit(1);}}}ptr[v2] = 0;return ptr;
}

-1转换与相关变量与函数命名

在这里插入图片描述

设置sub_25D5()

这里根据每次输入一个字符将分配得到的堆指针设置为字符指针类型

void __fastcall read_line()
{int high; // [rsp+Ch] [rbp-14h]int i; // [rsp+10h] [rbp-10h]int tmp_char; // [rsp+14h] [rbp-Ch]char *input_content_line; // [rsp+18h] [rbp-8h]high = 528;i = 0;input_content_line = (char *)malloc(0x210uLL);if ( !input_content_line )_exit(0);while ( 1 ){tmp_char = getchar();if ( tmp_char == (unsigned int)EOF || tmp_char == '\n' )break;input_content_line[i++] = tmp_char;if ( i >= high && high <= 2147483639 ){high += 496;input_content_line = (char *)realloc(input_content_line, high);if ( !input_content_line ){fwrite("mybash: allocation error\n", 1uLL, 0x19uLL, stderr);exit(1);}}}input_content_line[i] = 0;
}

sub_247F(char *a1)

_QWORD *__fastcall sub_247F(char *a1)
{int v2; // [rsp+10h] [rbp-20h]int v3; // [rsp+14h] [rbp-1Ch]_QWORD *ptr; // [rsp+18h] [rbp-18h]char *i; // [rsp+20h] [rbp-10h]_QWORD *v6; // [rsp+28h] [rbp-8h]v2 = 64;v3 = 0;v6 = malloc(0x200uLL);if ( !v6 )_exit(0);ptr = v6;for ( i = strtok(a1, " \t\r\n\a"); i; i = strtok(0LL, " \t\r\n\a") ){ptr[v3++] = i;if ( v3 >= v2 ){v2 += 64;ptr = realloc(ptr, 8LL * v2);if ( !ptr ){fwrite("mybash: allocation error\n", 1uLL, 0x19uLL, stderr);exit(1);}}}ptr[v3] = 0LL;return ptr;
}

设置sub_247F(char *a1)函数

这里i是地址,所以ptr应该是双指针
在这里插入图片描述

char **__fastcall split_string(char *content_line)
{int high; // [rsp+10h] [rbp-20h]int cur_pos; // [rsp+14h] [rbp-1Ch]char **split_content_ptr; // [rsp+18h] [rbp-18h]char *one_split_content_ptr; // [rsp+20h] [rbp-10h]char **temp_chunk_ptr; // [rsp+28h] [rbp-8h]high = 64;cur_pos = 0;temp_chunk_ptr = (char **)malloc(0x200uLL);if ( !temp_chunk_ptr )_exit(0);split_content_ptr = temp_chunk_ptr;for ( one_split_content_ptr = strtok(content_line, " \t\r\n\a");one_split_content_ptr;one_split_content_ptr = strtok(0LL, " \t\r\n\a") ){split_content_ptr[cur_pos++] = one_split_content_ptr;if ( cur_pos >= high ){high += 64;split_content_ptr = (char **)realloc(split_content_ptr, 8LL * high);if ( !split_content_ptr ){fwrite("mybash: allocation error\n", 1uLL, 0x19uLL, stderr);exit(1);}}}split_content_ptr[cur_pos] = 0LL;return split_content_ptr;
}

sub_23CA(const char **a1)

__int64 __fastcall sub_23CA(const char **a1)
{int i; // [rsp+1Ch] [rbp-4h]if ( !*a1 )return 1LL;for ( i = 0; i < (int)sub_1523(); ++i ){if ( !strcmp(*a1, (const char *)*(&off_5020 + i)) )return ((__int64 (__fastcall *)(const char **))funcs_2446[i])(a1);}printf("%s: ERROR\n", *a1);return 0LL;
}

设置sub_23CA(const char **a1)函数

在这里插入图片描述

__int64 __fastcall instruction_proccess(const char **split_content_ptr_array)
{int i; // [rsp+1Ch] [rbp-4h]if ( !*split_content_ptr_array )return 1LL;for ( i = 0; i < (int)return_7(); ++i ){if ( !strcmp(*split_content_ptr_array, struction_name_ptr_array[i]) )return struction_function_ptr_array[i](split_content_ptr_array);}printf("%s: ERROR\n", *split_content_ptr_array);return 0LL;
}

sub_1523()

__int64 sub_1523()
{return 7LL;
}

设置sub_1523()函数

__int64 return_7()
{return 7LL;
}

h更换数据形式

在这里插入图片描述
对应的各个字符串
在这里插入图片描述

更改各个函数名

在这里插入图片描述

__int64 __fastcall command_touch(__int64 a1)

__int64 __fastcall command_touch(__int64 a1)
{int v2; // [rsp+1Ch] [rbp-14h]void *ptr56; // [rsp+20h] [rbp-10h]SomeStruct *Instance; // [rsp+28h] [rbp-8h]v2 = 1;if ( !*(_QWORD *)(a1 + 8) )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( *(_QWORD *)(8LL * v2 + a1) ){ptr56 = qword_5150->ptr56;if ( (unsigned __int8)sub_13C9((__int64)ptr56, *(const char **)(8LL * v2 + a1)) != 1 ){++v2;}else{Instance = SomeStruct::CreateInstance();Instance->unkown_0 = 1;sub_166E(Instance, *(_QWORD *)(8LL * v2 + a1));if ( qword_5150->ptr56 )sub_1628(ptr56, Instance);elseqword_5150->ptr56 = Instance;++v2;}}return 1LL;
}

修改后的__int64 __fastcall command_touch(__int64 a1)

__int64 __fastcall command_touch(char **args)
{int parameter_position; // [rsp+1Ch] [rbp-14h]SomeStruct *main_save_instance_ptr_of_first_file_ptr; // [rsp+20h] [rbp-10h]SomeStruct *Instance_ptr; // [rsp+28h] [rbp-8h]parameter_position = 1;if ( !args[1] )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( args[parameter_position] ){main_save_instance_ptr_of_first_file_ptr = main_save_instance_ptr->first_son;if ( (unsigned __int8)SomeStruct::Folder_Not_Eixst(main_save_instance_ptr_of_first_file_ptr,args[parameter_position]) != 1 ){++parameter_position;}else{Instance_ptr = SomeStruct::CreateInstance();Instance_ptr->isfile = 1;SomeStruct::set_some_array(Instance_ptr, args[parameter_position]);if ( main_save_instance_ptr->first_son )sub_1628(main_save_instance_ptr_of_first_file_ptr, Instance_ptr);elsemain_save_instance_ptr->first_son = Instance_ptr;++parameter_position;}}return 1LL;
}

__int64 __fastcall command_mkdir(__int64 a1)

__int64 __fastcall command_mkdir(__int64 a1)
{char v1; // alint v3; // [rsp+1Ch] [rbp-14h]void *ptr56; // [rsp+20h] [rbp-10h]SomeStruct *Instance; // [rsp+28h] [rbp-8h]v3 = 1;if ( !*(_QWORD *)(a1 + 8) )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( *(_QWORD *)(8LL * v3 + a1) ){ptr56 = qword_5150->ptr56;((void (__fastcall *)())((char *)&sub_13C8 + 1))();if ( v1 != 1 ){fprintf(stderr, aMybashCannotCr, *(_QWORD *)(8LL * v3++ + a1));}else{Instance = SomeStruct::CreateInstance();Instance->unkown_0 = 0;Instance->ptr48 = qword_5150;sub_166E(Instance, *(_QWORD *)(8LL * v3 + a1));if ( qword_5150->ptr56 )sub_1628(ptr56, Instance);elseqword_5150->ptr56 = Instance;++v3;}}return 1LL;
}
void sub_13C8()
{JUMPOUT(0x13CALL);
}

修改后的__int64 __fastcall command_mkdir(const char **args)

__int64 __fastcall command_mkdir(const char **args)
{// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]parameter_position = 1;if ( !args[1] )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( args[parameter_position] ){main_save_instance_ptr_of_first = main_save_instance_ptr->first_son;if ( (unsigned __int8)SomeStruct::Folder_Not_Eixst(main_save_instance_ptr_of_first, args[parameter_position]) != 1 ){fprintf(stderr, aMybashCannotCr, args[parameter_position++]);}else{mkdir_create_Instance_ptr = SomeStruct::CreateInstance();mkdir_create_Instance_ptr->isfile = 0;    // 0为目录mkdir_create_Instance_ptr->parent = main_save_instance_ptr;SomeStruct::set_some_array(mkdir_create_Instance_ptr, args[parameter_position]);if ( main_save_instance_ptr->first_son )sub_1628(main_save_instance_ptr_of_first, mkdir_create_Instance_ptr);elsemain_save_instance_ptr->first_son = mkdir_create_Instance_ptr;++parameter_position;}}return 1LL;
}

此时发现void sub_13C8()函数又跳转

Tab键:反编译
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后得到的原void sub_13C8()函数

__int64 __fastcall sub_13C9(__int64 a1, const char *a2)
{while ( a1 ){if ( !strcmp((const char *)(a1 + 4), a2) )return 0LL;a1 = *(_QWORD *)(a1 + 40);}return 1LL;
}

注意

当一个函数分析有点棘手时可以查看其他引用该函数的地方

修改后的__int64 __fastcall command_cat(const char **args)

__int64 __fastcall command_cat(const char **args)
{unsigned __int64 high_parament_length_16; // raxvoid *v2; // rsp_BYTE v4[8]; // [rsp+8h] [rbp-70h] BYREFconst char **args_save; // [rsp+10h] [rbp-68h]char v6; // [rsp+1Fh] [rbp-59h]int parament_longest_length_more1; // [rsp+20h] [rbp-58h]int parameter_position; // [rsp+24h] [rbp-54h]SomeStruct *first_son; // [rsp+28h] [rbp-50h]__int64 parament_longest_length_more; // [rsp+30h] [rbp-48h]char *cat_file_name; // [rsp+38h] [rbp-40h]unsigned __int64 v12; // [rsp+40h] [rbp-38h]args_save = args;v12 = __readfsqword(0x28u);parameter_position = 0;v6 = 0;parament_longest_length_more1 = 0;first_son = 0LL;while ( args_save[++parameter_position] ){if ( strlen(args_save[parameter_position]) > parament_longest_length_more1 )parament_longest_length_more1 = strlen(args_save[parameter_position]) + 1;}parament_longest_length_more = parament_longest_length_more1 - 1LL;high_parament_length_16 = 16 * ((parament_longest_length_more1 + 15LL) / 0x10uLL);while ( v4 != &v4[-(high_parament_length_16 & 0xFFFFFFFFFFFFF000LL)] );v2 = alloca(high_parament_length_16 & 0xFFF);if ( (high_parament_length_16 & 0xFFF) != 0 )*&v4[(high_parament_length_16 & 0xFFF) - 8] = *&v4[(high_parament_length_16 & 0xFFF) - 8];cat_file_name = v4;                           // 上面都没啥用,v2,v4后面都没用到parameter_position = 1;if ( !args_save[1] )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( args_save[parameter_position] ){first_son = current_directory_ptr->first_son;strcpy(cat_file_name, args_save[parameter_position]);while ( first_son ){if ( !strcmp(cat_file_name, first_son->file_name) ){if ( first_son->file_content_ptr )puts(first_son->file_content_ptr);v6 = 1;break;}first_son = first_son->next_ptr;}if ( v6 != 1 )fprintf(stderr, "mybash: %s: No such file or directory\n", args_save[parameter_position]);++parameter_position;}return 1LL;
}

修改后的__int64 __fastcall command_rm(const char **args)

__int64 __fastcall command_rm(const char **args)
{// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]parameter_position = 1;if ( !args[1] )fwrite("mybash: missing operand\n", 1uLL, 0x18uLL, stderr);while ( args[parameter_position] ){son_file = current_directory_ptr->first_son;success_flag = 0;while ( son_file ){if ( !strcmp(son_file->file_name, args[parameter_position]) ){success_flag = 1;if ( IsFile(son_file) ){memset(son_file->file_name, 0, sizeof(son_file->file_name));if ( son_file->file_content_ptr )free(son_file->file_content_ptr);SomeStruct::unlink_file(son_file);}else{fprintf(stderr, "mybash: '%s': Is a directory\n", args[parameter_position]);}break;}son_file = son_file->next_ptr;}if ( success_flag != 1 )fprintf(stderr, "mybash: '%s': No such file or directory\n", args[parameter_position]);++parameter_position;}return 1LL;
}

修改后的__int64 __fastcall command_echo(char **args)

__int64 __fastcall command_echo(char **args)
{SomeStruct *v2; // rbxSomeStruct *v3; // rbxint parameter_position; // [rsp+14h] [rbp-3Ch]int i; // [rsp+14h] [rbp-3Ch]int content_length; // [rsp+18h] [rbp-38h]int last_parameter_position; // [rsp+1Ch] [rbp-34h]int input_content_length; // [rsp+24h] [rbp-2Ch]SomeStruct *current_son_file; // [rsp+28h] [rbp-28h] BYREFconst char *last_parameter_ptr; // [rsp+30h] [rbp-20h]unsigned __int64 v11; // [rsp+38h] [rbp-18h]v11 = __readfsqword(0x28u);parameter_position = 0;if ( args[1] ){do++parameter_position;while ( args[parameter_position] );last_parameter_position = parameter_position - 1;if ( Is_No_Echo_to_File(args[parameter_position - 2]) ){for ( i = 1; i < last_parameter_position; ++i )printf(args[i]);puts(args[last_parameter_position]);return 1LL;}else{current_son_file = current_directory_ptr->first_son;last_parameter_ptr = args[last_parameter_position];if ( Is_Exist_File(&current_son_file, last_parameter_ptr) != 1 ){fprintf(stderr, "mybash: %s: No such file\n", last_parameter_ptr);return 1LL;}else if ( IsFile(current_son_file) ){if ( current_son_file->file_content_ptr ){content_length = SomeStruct::Get_Content_length(current_son_file->file_content_ptr);}else{content_length = 0x1F0;v2 = current_son_file;v2->file_content_ptr = malloc(0x1F0uLL);if ( !current_son_file->file_content_ptr )_exit(0);}input_content_length = strlen(args[last_parameter_position - 2]);while ( input_content_length > content_length )content_length += 0x1F0;if ( content_length > SomeStruct::Get_Content_length(current_son_file->file_content_ptr) ){v3 = current_son_file;v3->file_content_ptr = realloc(current_son_file->file_content_ptr, content_length);}strncpy(current_son_file->file_content_ptr, args[last_parameter_position - 2], input_content_length);return 1LL;}else{fprintf(stderr, "mybash: %s: Is a directory\n", last_parameter_ptr);return 1LL;}}}else{putchar(10);return 1LL;}
}

修改后的__int64 __fastcall command_cd(char **arg)

__int64 __fastcall command_cd(char **arg)
{size_t dest_length; // rbxsize_t current_file_name_length; // raxint main_save_instance_ptr_file_name_length; // [rsp+18h] [rbp-38h]const char *after_dlim_para; // [rsp+20h] [rbp-30h]SomeStruct *current_file; // [rsp+28h] [rbp-28h]char delim[2]; // [rsp+36h] [rbp-1Ah] BYREFunsigned __int64 v8; // [rsp+38h] [rbp-18h]v8 = __readfsqword(0x28u);if ( arg[1] ){if ( arg[2] ){fwrite("mybash: too many arguments\n", 1uLL, 0x1BuLL, stderr);}else{strcpy(delim, "/");for ( after_dlim_para = strtok(arg[1], delim); after_dlim_para; after_dlim_para = strtok(0LL, delim) ){if ( strcmp(after_dlim_para, ".") ){if ( !strcmp(after_dlim_para, "..") ){if ( current_directory_ptr->parent ){main_save_instance_ptr_file_name_length = strlen(current_directory_ptr->file_name);current_directory_path[(strlen(current_directory_path) - 1 - main_save_instance_ptr_file_name_length)] = 0;current_directory_ptr = current_directory_ptr->parent;// 当前目录更新为之前目录的父目录}}else{current_file = current_directory_ptr->first_son;if ( SomeStruct::File_Not_Eixst(current_file, after_dlim_para) ){fprintf(stderr, "mybash: %s: No such file or directory\n", after_dlim_para);return 1LL;}while ( current_file && strcmp(current_file->file_name, after_dlim_para) )current_file = current_file->next_ptr;if ( !SomeStruct::IsDirectory(current_file) ){fwrite("something wrong happened\n", 1uLL, 0x19uLL, stderr);return 1LL;}current_directory_ptr = current_file;dest_length = strlen(current_directory_path);if ( dest_length + strlen(current_file->file_name) + 1 <= 0x4F ){current_file_name_length = strlen(current_file->file_name);strncat(current_directory_path, current_file->file_name, current_file_name_length);*&current_directory_path[strlen(current_directory_path)] = 47;}}}}}}else{fwrite("mybash: expected argument\n", 1uLL, 0x1AuLL, stderr);}return 1LL;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2808785.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构与算法】(20)高级数据结构与算法设计之 Greedy Algorithm 贪心算法 代码示例与详细讲解

目录 4.2 Greedy Algorithm1) 贪心例子DijkstraPrimKruskal 2) 零钱兑换问题有几个解&#xff08;零钱兑换 II&#xff09;Leetcode 518最优解&#xff08;零钱兑换&#xff09;- 穷举法 Leetcode 322最优解&#xff08;零钱兑换&#xff09;- 贪心法 Leetcode 322 3) Huffman …

线程池的常用实现及执行流程

线程池 线程池线程池接口线程池参数线程池分类动态数目线程池固定数目线程池单例线程池任务调度线程池 线程池的执行流程 线程池 线程池接口 线程池参数 1、corePoolSize&#xff1a;核心线程数&#xff0c;线程池中最少线程&#xff0c;核心线程不会被回收。 2、maximumPoo…

6-pytorch-神经网络搭建

b站小土堆pytorch教程学习笔记 1.神经网络骨架搭建&#xff1a;Containers 官方文档代码&#xff1a; import torch.nn as nn import torch.nn.functional as Fclass Model(nn.Module):def __init__(self):super().__init__()self.conv1 nn.Conv2d(1, 20, 5)self.conv2 nn.…

nccl2安装指南

https://developer.nvidia.com/nccl/nccl-download 旧版本安装: https://developer.nvidia.com/nccl/nccl-legacy-downloads 找到你对应的CUDA版本 我这里选择 deb 文件安装了 sudo dpkg -i nccl-local-repo-ubuntu2004-2.16.5-cuda11.8_1.0-1_amd64.debsudo cp /var/nccl-lo…

深度解析:Integer.parseInt() 源码解读

深度解析&#xff1a;Integer.parseInt() 源码解读 关键要点 解析字符&#xff1a;用于将字符转换为对应的数字值 Character.digit(s.charAt(i),radix) 确定limit&#xff1a;根据正负号分别设定 int limit -Integer.MAX_VALUE;【正】 limit Integer.MIN_VALUE;【负】 负数…

车载测试面试:题库+项目

车载测试如何面试&#xff08;面试技巧&#xff09;https://blog.csdn.net/2301_79031315/article/details/136229809 入职车载测试常见面试题(附答案&#xff09;https://blog.csdn.net/2301_79031315/article/details/136229946 各大车企面试题汇总&#xff08;含答案&am…

mac下使用jadx反编译工具

直接执行步骤&#xff1a; 1.创建 jadx目录 mkdir jadx2.将存储库克隆到目录 git clone https://github.com/skylot/jadx.git 3. 进入 jadx目录 cd jadx 4.执行编译 等待片刻 ./gradlew dist出现这个就代表安装好了。 5.最后找到 jadx-gui 可执行文件&#xff0c;双击两下…

为什么TestNg会成为Java测试框架的首选?还犹豫什么,看它!

上一篇自动化测试我们大概了解了测试的目标、测试的技术选型以及搭建平台的目标及需求&#xff0c;也确定了自动化测试方案以testNg作为整个测试流程贯穿的基础支持框架&#xff0c;那么testNg究竟有什么特点&#xff1f;本篇开始我们来详细的学习testNg这个测试框架。 为什么要…

基于Android的校园请假App的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

java面试题之mysql篇

1、数据库索引 ​​​​​​​ 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她&#xff0c;则与在表中搜索所有的行相比&#xff0c;索引有助于更快地获取信息。 索引的一个主要…

protobuf简单使用(二)

介绍 上一节中&#xff0c;我们介绍了protobuf&#xff0c;简单来说&#xff0c;它是一种消息数据格式&#xff0c;其作用类似于json&#xff0c;但是比json的使用效率要高。 除此以外&#xff0c;我们介绍了protobuf的简单使用&#xff0c;也就是如何可以像使用json一样&…

Springboot+vue的社区医疗综合服务平台(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的社区医疗综合服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的社区医疗综合服务平台&#xff0c;采用M&#xff08;m…

五、数组——Java基础篇

六、数组 1、数组元素的遍历 1.1数组的遍历&#xff1a;将数组内的元素展现出来 1、普通for遍历&#xff1a;根据下表获取数组内的元素 2、增强for遍历&#xff1a; for&#xff08;数据元素类型 变量名&#xff1a;数组名&#xff09;{ 变量名&#xff1a;数组内的每一个值…

面试经典150题【21-30】

文章目录 面试经典150题【21-30】6.Z字形变换28.找出字符串中第一个匹配项的下标68.文本左右对齐392.判断子序列167.两数之和11.盛最多水的容器15.三数之和209.长度最小的子数组3.无重复字符的最长子串30.串联所有单词的子串 面试经典150题【21-30】 6.Z字形变换 对于“LEETC…

【Java多线程】对线程池的理解并模拟实现线程池

目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多&#xff0c;例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是&#xff1a;&#xff08;提高效率&#xff09; 1…

计网day5

六 传输层 6.1 传输层概述 6.2 UDP协议 6.3 TCP协议 TCP连接管理&#xff1a; TCP可靠传输&#xff1a; TCP拥塞控制&#xff1a;

[ROS 系列学习教程] rosbag 命令行介绍

ROS 系列学习教程(总目录) 本文目录 rosbag 命令行1.1 rosbag check1.2 rosbag compress1.3 rosbag decompress1.4 rosbag filter1.5 rosbag fix1.6 rosbag info1.7 rosbag play1.8 rosbag record1.9 rosbag reindex 有时我们需要将 topic 中的数据保存下来以便后面分析&#x…

istio实战:springboot项目在istio中服务调用

目录 一、前言二、准备工作三、问题排查四、总结参考资料 一、前言 在经过前面几天k8s和Istio的安装之后&#xff0c;开始进入最核心的阶段。微服务在抛弃传统的服务注册和服务发现之后&#xff0c;是怎么在istio怎么做服务间的调用的呢&#xff1f;本次实战花费了我2-3天的时…

【监控】grafana图表使用快速上手

目录 1.前言 2.连接 3.图表 4.job和path 5.总结 1.前言 上一篇文章中&#xff0c;我们使用spring actuatorPrometheusgrafana实现了对一个spring boot应用的可视化监控。 【监控】Spring BootPrometheusGrafana实现可视化监控-CSDN博客 其中对grafana只是打开了一下&am…

Seata分布式事务实战AT模式

目录 分布式事务简介 典型的分布式事务应用场景 两阶段提交协议(2PC) 2PC存在的问题 什么是Seata&#xff1f; Seata的三大角色 Seata AT模式的设计思路 一阶段 二阶段 Seata快速开始 Seata Server&#xff08;TC&#xff09;环境搭建 db存储模式Nacos(注册&配…