bomb 实验

GDB常用命令:

GDB调试常用命令-CSDN博客

原理:

编译与反汇编过程-CSDN博客

Bomb实验实现

阶段一: 

分析

  • 分配空间sub $0x8,%rsp 为局部变量分配栈空间。
  • 设置参数mov $0x402400,%esi 将字符串地址加载到 %esi
  • 比较字符串call 401338 <strings_not_equal> 调用函数比较字符串。
  • 判断结果test %eax,%eax 检查返回值,决定是否触发“炸弹”。
  • 触发或返回:不相等则 call 40143a <explode_bomb>,相等则恢复栈指针并返回。

答案:        "Border relations with Canada have never been better." 

 结构化汇编代码:

esi = $0x402400         // 字符串地址
strings_not_equal()
if eax == 0 {
    release_sp()
}else{
    explode_bomb()
}

 C_Like代码:

//  phase_1
int main(){
    std::string string_ = read();
    bool check = strings_not_equal(string_,"对应参数");
    if (!check){
        explode_bomb();
    }
    return 0;
}

阶段二(数组:

注意:

(1)区分清楚赋值是地址(lea),还是数据(mov)

(2)栈分配40个字节,剩余的字节可能用于对齐或存储其他局部变量(如寄存器的保存) 

(3)寄存器地址偏移通过逐步调整通用寄存器(如 rbx)的值,遍历数组中的元素。例如,int 类型增加 4 字节,char 类型增加 1 字节。

 (4)答案:        1 2 4 8 16 32

 结构化汇编代码:

阶段二:
rsp -= 0x28   
rsi = rsp

read_six_numbers()  

if *rsp != 1{
    explode_bomb()
}

rbx = rsp + 4       // 栈顶第2个元素地址
rbp = rsp + 0x18    // 栈顶第6个元素地址

do{
    eax = *(rbx - 4)   // rbx前一个元素
    if *rbx - eax*2 !=0 {      
        explode_bomb()
    } 
    rbx += 4        // rbx指向下一个元素
}while (rbx - rbp <= 0) // // rbx为栈顶第7个元素地址(实际不存在)

...释放栈帧
rsp += 0x28

C_Like代码:

int main(){
    int array[6];

    read_six_numbers(array);

    // 检查第一个数字是否为1
    if(array[0] == 1){
        explode_bomb();
    }

    // 检查剩余数字是否满足条件
    for(int i = 1; i < 6; i++){
        if(array[i] != array[i-1] * 2){
            explode_bomb();
        }
    }

    return 0;
}

阶段三(switch: 

注意:

(1)cmpl $0x7, 0x8(%rsp) 这条指令是将 rsp + 0x08 处的内存内容(值)与 0x07 进行比较,而不是比较地址本身。

(2)调用函数前,rdi第一个参数,rsi第二个参数,rdx第三个参数,rcx第四个参数

sscanf 函数的核心参数如下:

输入字符串(RDI):char* output
格式字符串(RSI):定义解析规则,例如 "%d %d"。
变量地址(RDX 和 RCX):用于存储解析后的数据,即 x 和 y 的地址。

(3)0x402470 是跳转表的基地址(起始地址)

  400f75:	ff 24 c5 70 24 40 00 	jmp    *0x402470(,%rax,8)

(4) 例如:

0         0xcf
0         207
1         311
2         707
3         256
4         389
5         206
6         682
7         327

 结构化汇编代码:

// Phase 3

rsp = rsp - 0x18
    // 调用函数前参数设置   (output为rdi   num_1)
rcx = rsp + 0xc     // num_4
rdx = rsp + 8       // num_3
esi = $0x4025cf     // num_2

eax = 0             // 获取函数返回值
__isoc99_sscanf@plt()

if eax <= 1 {   //  有符号比较
    explode_bomb()
}

if *(rsp + 8) - 7 > 0 {    //  无符号比较
    explode_bomb()
}

eax = *(rsp + 8)
jmp 0x402470 + 8 *eax

switch(x) {
    case 0x400f7c:
        eax = 0xcf;
        break;
    case 0x400f83:
        eax = 0x2c3;
        break;
    case 0x400f8a:
        eax = 0x100;
        break;
    case 0x400f91:
        eax = 0x185;
        break;
    case 0x400f98:
        eax = 0xce;
        break;
    case 0x400f9f:
        eax = 0x2aa;
        break;
    case 0x400fa6:
        eax = 0x147;
        break;
    case 0x400fad:
        call explode_bomb();
        break;
    case 0x400fb2:
        eax = 0x0;
        break;
    case 0x400fb9:
        eax = 0x137;
}


if eax != *(rsp + 0xc){
    explode_bomb()
}

ret

 C_Like代码:

//  phase_3
int main(char * output){
    int x,y;
    int  check = sscanf(output,"%d %d",&x,&y); // 四个元素

    if (check <= 1){
         explode_bomb();
    }

    if(x > 7){
        explode_bomb();
    }

    int ret;
    switch (x) {
        case 0:
            ret = 0xcf; // corresponding to 0x400f7c
            break;
        case 1:
            ret = 0x2c3; // corresponding to 0x400f83
            break;
        case 2:
            ret = 0x100; // corresponding to 0x400f8a
            break;
        case 3:
            ret = 0x185; // corresponding to 0x400f91
            break;
        case 4:
            ret = 0xce; // corresponding to 0x400f98
            break;
        case 5:
            ret = 0x2aa; // corresponding to 0x400f9f
            break;
        case 6:
            ret = 0x147; // corresponding to 0x400fa6
            break;
        case 7:
            explode_bomb(); // corresponding to 0x400fad
            break;
        case 8:
            ret = 0x0; // corresponding to 0x400fb2
            break;
        case 9:
            ret = 0x137; // corresponding to 0x400fb9
            break;
    }
    if (ret != y){
        explode_bomb();
    }

    return 0;
}

阶段四(递归: 

分析

(1)sar    %eax相当于 sar $1,eax        (eax右移1位

(2)func_4功能:

  • 找到目标值 x:返回 0
  • 在左半部分找到 x:返回偶数。
  • 在右半部分找到 x:返回奇数。

总体结果: 

  • 始终在左半部分查找,返回 0
  • 有一次出现在右半部分,返回非0

(3)要求:        返回值必须为0,y也必须为0        (eg.        x: 1        y:0

 结构化汇编代码:

void phase_4() {
    // 减小栈指针,准备局部变量空间
    rsp -= 18;

    // 函数参数设置
    int* num_4 = (int*)(rsp + 0xc); // num_4 (y)
    int* num_3 = (int*)(rsp + 8);   // num_3 (x)

    // 读取用户输入
    esi = 0x4025cf;  // 指向输入格式字符串
    eax = 0;
    int result = __isoc99_sscanf(esi, "%d %d", num_4, num_3);

    // 判断输入是否合法
    if (result != 2) {
        explode_bomb();
    }

    // 判断 num_3 是否超出范围
    if (*num_3 > 0xe) {
        explode_bomb();
    }

    // 设置参数,准备调用 func_4
    int num_2 = 0;        // num_2
    int num_1 = *num_3;   // num_1
    int max_value = 0xe;  // 最大值 (edx)

    // 调用 func_4
    eax = func_4(num_1, num_2, max_value);

    // 判断 func_4 的返回值是否合法
    if (eax <= 0) {
        explode_bomb();
    } else {
        // 判断 num_4 是否为0
        if (*num_4 != 0) {
            explode_bomb();
        }
    }

    // 恢复栈指针并返回
    rsp += 24;
    return;
}

int func_4(int num_1, int num_2, int max_value) {
    // 减小栈指针,准备局部变量空间
    rsp -= 8;

    // 计算中间值
    int mid = (max_value - num_2) / 2 + num_2;

    // 递归处理
    if (mid > num_1) {
        max_value = mid - 1;
        eax = func_4(num_1, num_2, max_value);
        eax *= 2;
    } else if (mid < num_1) {
        num_2 = mid + 1;
        eax = func_4(num_1, num_2, max_value);
        eax = eax * 2 + 1;
    } else {
        eax = 0;
    }

    // 恢复栈指针并返回
    rsp += 8;
    return eax;
}

 C_Like代码:

int func_4(int target, int low, int high) {
    int range_size = high - low;    // 当前搜索范围的大小
    range_size = (range_size + (range_size >> 31)) >> 1;   // 处理符号位并计算中点偏移量
    int mid = range_size + low;     // 计算当前中间点的值

    if(mid > target) {
        return 2 * func_4(target, low, mid - 1); // 在左半部分继续搜索
    } else if(mid < target) {
        return 2 * func_4(target, mid + 1, high) + 1; // 在右半部分继续搜索
    } else {
        return 0; // 找到目标值,返回0
    }
}



int main(char *output) {
    int x, y;
    int check = sscanf(output, "%d %d", &x, &y); // 解析用户输入
    if (check != 2) {
        explode_bomb(); // 如果输入格式不对,触发炸弹
    }

    if (x > 14) {
        explode_bomb(); // 如果 x 超过 14,触发炸弹
    }
    // x 小于等于 14

    check = func_4(x, 0, 14); // 调用 func_4 进行计算
    
    if (check != 0 || y != 0) {
        explode_bomb(); // 如果返回值不正确,触发炸弹 
    }

    return 0;
}

阶段五: 

分析

(1)nopl (%rax) 用于指令对齐和填充特定字节

(2)repz ret 提供防攻击优化,提升特定处理器性能;ret 为标准返回指令。

(3)在字符串处理中,每个字符占 1 字节add $0x1, %rdxrdx 指向下一个字符的地址

(4)__stack_chk_fail@plt() 防止攻击,检查金丝雀值

(5)flyers六个字母对应maduiersnfotvbyl的下标分别为 9 15 14 5 6 7 ,对应ASCIL表编码进行&0xf操作后低四位

答案:

  • IONEFG
  • ionefg

 结构化汇编代码:

// phase_5

int string_length(string * str){
    if(str == 0){
        return 0;
    }
    string * str_offset_addr = str

    do{
        str_offset_addr += 1
        str_len = str_offset_addr - str
    }
    while(*str_offset_addr != 0);

    return str_len;
}


 void return_(){
    eax = edx        
    pop rbx
    pop rbp
    pop r12
    ret
};

int strings_not_equal(){
    push r12
    push rbp
    push rbx
    rbx = rdi
    rbp = rsi
    string_length()
    r12 = eax
    rdi = rbp
    string_length()
    edx = 1

    if(r12 != eax){
        return_();
    }

    eax = *rbx

    if(al == 0){
        edx = 0
        return_();
    }


    if(al == *rbp){ 
        while(true){
            rbx += 1
            rbp += 1
            eax = *(rbx)
            
            if(al == 0){
                edx = 0
                return_();
            }

            if(al != *rbp){
                edx = 1
                return_();
            }
        }
    }else{
        edx = 1
        return_();
    }

}

void phase_5(){

    push rbx
    rsp -= 0x20
    rbx = rdi 
    rax = *(fs + 0x28)
    rax = *(rsp + 0x18) 
    int check = string_length();
    if(check != 6){
        explode_bomb()
    }

    eax = 0
    do{
        ecx = *(rbx + rax)
        *(rsp) = cl
        rdx = *(rsp)

        edx = edx & 0xf
        edx = *(rdx + 0x4024b0)

        *(rsp + rax + 16) = dl
        rax += 1 
    }while(rax != 6)

    *(rsp + 0x16) = 0
    esi = 0x40245e
    rdi = rsp + 16
    int check_ = strings_not_equal()
    if(check_ != 0){
        explode_bomb()
    }
    rax = *(rsp + 0x18)

    rax ^= *(fs + 0x28)
    if(rax != 0){
        __stack_chk_fail@plt()      // 检测金丝雀值
    }     

    rsp += 0x20
    pop rbx
    ret
}

 C_Like代码:

// phase_5


int string_length(string * str){
    if(!(*str)[0]){
        return 0;
    }
    string * str_offset_addr = str;
    int str_len = 0;

    do{
        str_offset_addr += 1;
        str_len = str_offset_addr - str;
    }
    while((*str_offset_addr)[0]);

    return str_len;
}

bool strings_not_equal(string * str1, string * str2){
    if(string_length(str1) != string_length(str2)){
        return true;
    }

    if(!(*str1)[0]){
        return false;
    }
    
    int i = 0;

    while((*str1)[i] == (*str2)[i]){
        i++;
        if(!(*str1)[i]){
            return false;
        }

        if((*str1)[i] != (*str2)[i]){
            return true;
        }
    }
    return true;
}

void phase_5(){
    string output = "maduiersnfotvbylSo";
    int len = string_length(&output);
    if(len != 6){
        explode_bomb();
    }
    string *other;
    for(int i = 0;i < 6;i++){
        char c = (output)[i]; 
        c = c & 0xf;
        (*other)[i] = *(char*)(0x4024b0 + c);
    }

    string target = "flyers";
    bool check = strings_not_equal(other, &target);
    if(check){
        explode_bomb();
    }
}

阶段六:

分析

(1)链表结构:        嵌套解指针的结构

            for(eax = 1;eax == ecx;eax += 1){
                rdx = rdx + 8
            }   

(2)32位系统中,指针为4位,故这个结构体大小为8位

typedef struct {
    int val;
    Node* node_next;
}Node;

(3)GDB命令

1.查看寄存器的值

info reg rsp

2.查看内存的值

x/gx 0x7fffffffe000 + 0x20

x: 表示 examine(查看),用于查看内存。
/gx: 指定查看格式。
g: 表示以 8 字节(64 位)长的整数格式查看。
x: 表示以十六进制格式显示值。

x/gx 0x00000000006032d0 返回 0x000000010000014c:

下一个节点的地址:0x00000001
节点的值:0x0000014c (即 332)

(4)链表Node地址数组 

0x6032F0    链表地址数组第一个

0x6032F0 + 8 指向 next_node地址

Node_next地址 :

mov    0x20(%rsp),%rbx  ->     rbx = 0x6032F0
mov    %rbx,%rcx        ->     rcx = 0x6032F0

mov    (%rax),%rdx      ->     rdx = 0x6032F0
mov    %rdx,0x8(%rcx)   ->     *(0x6032F0 + 8) = 0x603300
(*(0x6032F0 + 8) 指向第一个元素的next 地址)

Node_val:

mov    0x20(%rsp),%rbx  ->     rbx = 0x6032F0


rax = *(rbx + 8)        ->     rbx + 8        链表head地址
                        ->     *(rbx + 8)     指向head->Next_Node的地址

eax = *rax              ->     *(*(rbx + 8))  head->Next_Node的val

 (5)连接链表

    for (int i = 0; i < 5; i++) {
        node_array[i]->next = node_array[i+1];
    }

 栈中存储:

node1 (0x6032d0) -> node2 (0x6032e0) -> node3 (0x6032f0) -> node4 (0x603300) -> node5 (0x603310) -> node6 (0x603320)
332                -> 168                -> 924                -> 691                -> 477                -> 443

倒序推论:

最后链表值大小必须降序:      

924 -> 691 -> 477 -> 443 -> 332 -> 168

3, 4, 5, 6, 1, 2

然后7作差,整型数组答案:  

4 -> 3 -> 2 -> 1 -> 6 -> 5

 友好的汇编代码(重点,作为汇编阅读方式):

00000000004010f4 <phase_6>:

  4010fc:	48 83 ec 50          	sub    $0x50,%rsp
  401100:	49 89 e5             	mov    %rsp,%r13
  401103:	48 89 e6             	mov    %rsp,%rsi
  401106:	e8 51 03 00 00       	call   40145c <read_six_numbers>
  40110b:	49 89 e6             	mov    %rsp,%r14

  40110e:	41 bc 00 00 00 00    	mov    $0x0,%r12d   # i = 0
# num_1:  外层循环
-------------------------------------------------
  401114:	4c 89 ed             	mov    %r13,%rbp
  401117:	41 8b 45 00          	mov    0x0(%r13),%eax
  40111b:	83 e8 01             	sub    $0x1,%eax

      # 爆炸(eax > 6)
      ---------------------
  40111e:	83 f8 05             	cmp    $0x5,%eax
  401121:	76 05                	jbe    401128 <phase_6+0x34>
  401123:	e8 12 03 00 00       	call   40143a <explode_bomb>  
      ---------------------

  401128:	41 83 c4 01          	add    $0x1,%r12d             # i += 1

  40112c:	41 83 fc 06          	cmp    $0x6,%r12d             # i == 6
  401130:	74 21                	je     401153 <phase_6+0x5f>  # 退出整个循环

  401132:	44 89 e3             	mov    %r12d,%ebx
  #  内层循环
  -------------------------------------------------  
  401135:	48 63 c3             	movslq %ebx,%rax
  401138:	8b 04 84             	mov    (%rsp,%rax,4),%eax

      # 爆炸(eax == *rbp)
      ---------------------
  40113b:	39 45 00             	cmp    %eax,0x0(%rbp)
  40113e:	75 05                	jne    401145 <phase_6+0x51>
  401140:	e8 f5 02 00 00       	call   40143a <explode_bomb>
      ---------------------

  401145:	83 c3 01             	add    $0x1,%ebx              # j += 1

  401148:	83 fb 05             	cmp    $0x5,%ebx              # j > 5
  40114b:	7e e8                	jle    401135 <phase_6+0x41>  # 退出内层循环

  ------------------------------------------------- 

  40114d:	49 83 c5 04          	add    $0x4,%r13
  401151:	eb c1                	jmp    401114 <phase_6+0x20>

-------------------------------------------------------------



  401153:	48 8d 74 24 18       	lea    0x18(%rsp),%rsi
  401158:	4c 89 f0             	mov    %r14,%rax  # addr = rsp
  40115b:	b9 07 00 00 00       	mov    $0x7,%ecx
# num_2 循环
-------------------------------------------------------------
      401160:	89 ca                	mov    %ecx,%edx
      401162:	2b 10                	sub    (%rax),%edx
      401164:	89 10                	mov    %edx,(%rax)
      401166:	48 83 c0 04          	add    $0x4,%rax              # addr += 4

      40116a:	48 39 f0             	cmp    %rsi,%rax              # addr == rsp + 0x18
      40116d:	75 f1                	jne    401160 <phase_6+0x6c>  # 退出循环
-------------------------------------------------------------


  40116f:	be 00 00 00 00       	mov    $0x0,%esi
  401174:	eb 21                	jmp    401197 <phase_6+0xa3>

# num_3 外层循环
-------------------------------------------------------------
  # num_3 内层循环1
  -------------------------------------------------------------
  401176:	48 8b 52 08          	mov    0x8(%rdx),%rdx
  40117a:	83 c0 01             	add    $0x1,%eax
  40117d:	39 c8                	cmp    %ecx,%eax
  40117f:	75 f5                	jne    401176 <phase_6+0x82>   
  -------------------------------------------------------------

  401181:	eb 05                	jmp    401188 <phase_6+0x94>

  # num_3 循环开始
  # num_3 内层循环2
  -------------------------------------------------------------
    401183:	ba d0 32 60 00       	mov    $0x6032d0,%edx
    401188:	48 89 54 74 20       	mov    %rdx,0x20(%rsp,%rsi,2)
    40118d:	48 83 c6 04          	add    $0x4,%rsi
    401191:	48 83 fe 18          	cmp    $0x18,%rsi
    401195:	74 14                	je     4011ab <phase_6+0xb7>
  num_3 start: 
    401197:	8b 0c 34             	mov    (%rsp,%rsi,1),%ecx
    40119a:	83 f9 01             	cmp    $0x1,%ecx
    40119d:	7e e4                	jle    401183 <phase_6+0x8f>
  -------------------------------------------------------------

  40119f:	b8 01 00 00 00       	mov    $0x1,%eax
  4011a4:	ba d0 32 60 00       	mov    $0x6032d0,%edx
  4011a9:	eb cb                	jmp    401176 <phase_6+0x82>
-------------------------------------------------------------

  4011ab:	48 8b 5c 24 20       	mov    0x20(%rsp),%rbx
  4011b0:	48 8d 44 24 28       	lea    0x28(%rsp),%rax
  4011b5:	48 8d 74 24 50       	lea    0x50(%rsp),%rsi
  4011ba:	48 89 d9             	mov    %rbx,%rcx

# num_4 循环
-------------------------------------------------------------
    
    4011bd:	48 8b 10             	mov    (%rax),%rdx
    4011c0:	48 89 51 08          	mov    %rdx,0x8(%rcx)
    4011c4:	48 83 c0 08          	add    $0x8,%rax

    // break;  
    4011c8:	48 39 f0             	cmp    %rsi,%rax
    4011cb:	74 05                	je     4011d2 <phase_6+0xde>

    4011cd:	48 89 d1             	mov    %rdx,%rcx
    4011d0:	eb eb                	jmp    4011bd <phase_6+0xc9>
-------------------------------------------------------------

  4011d2:	48 c7 42 08 00 00 00 	movq   $0x0,0x8(%rdx)
  4011d9:	00 
  4011da:	bd 05 00 00 00       	mov    $0x5,%ebp


# num_5 循环
-------------------------------------------------------------

    4011df:	48 8b 43 08          	mov    0x8(%rbx),%rax
    4011e3:	8b 00                	mov    (%rax),%eax
    4011e5:	39 03                	cmp    %eax,(%rbx)
    4011e7:	7d 05                	jge    4011ee <phase_6+0xfa>
    4011e9:	e8 4c 02 00 00       	call   40143a <explode_bomb>
    4011ee:	48 8b 5b 08          	mov    0x8(%rbx),%rbx
    4011f2:	83 ed 01             	sub    $0x1,%ebp
    4011f5:	75 e8                	jne    4011df <phase_6+0xeb>
-------------------------------------------------------------


  4011f7:	48 83 c4 50          	add    $0x50,%rsp
  401203:	c3                   	ret 

 结构化汇编代码:


void phase_6(){
    r13 = rsp
    rsi = rsp
    read_six_numbers()
    r14 = rsp
    r12 = 0         # i = 0
# num_1 外层循环
-------------------------------------------------   
    rbp = r13   (rsp 副本)
    eax =  *rsp - 1

    if(eax <= 5){
        explode_bomb()
    }

    r12 += 1        # i += 1
                    # 退出整个循环(i == 6)
    if(r12 == 6){   
        break;
    }

    ebx = r12   # j = r12

    # 内层循环
    -------------------------------------------------   
    rax = ebx
    eax = *(rsp + rax + 4)

    if(rbp == eax){
        explode_bomb()
    }

    ebx += 1    # j += 1
                # 退出内层循环(j > 5)
    if(ebx > 5){
        break;
    }
    -------------------------------------------------   
    r13 += 4

-------------------------------------------------   

    rax = r14   # addr = rsp

# num_2 循环
-------------------------------------------------------------
    for(rax = rsp;rax != rsp + 0x18;rax += 4){
        edx = 7
        edx -= *rax 
        *rax = edx        
    }

-------------------------------------------------------------

# num_3 循环
-------------------------------------------------------------
 
    for(rsi = 0;rsi != 0x18;rsi += 4){
        ecx = *(rsp + rsi)
        if(ecx > 1){
            edx = 0x6032d0          
        }else{
            edx = 0x6032d0 
            for(eax = 1;eax == ecx;eax += 1){
                rdx = rdx + 8
            }   
        }            
        *(rsp + rsi*2 + 0x20) = rdx   
    }
-------------------------------------------------------------

    rcx = *(rsp + 0x20)

# num_4 循环(关于rax的操作只有 rax+=8 
#                   => 可以预见不可能中途退出,故可以直接判断为for循环)
-------------------------------------------------------------
    for(rax = rsp + 0x28;rax != rsp + 0x50;){
        rdx = *rax
        *(rcx + 8) = rdx
        rax += 8
        if(rax == rsp + 0x50){
            break;
        }
        rcx = rdx        
    }

-------------------------------------------------------------
 
    *(rdx + 8) = 0
    
# num_5 循环
-------------------------------------------------------------
    for(ebp = 5;ebp != 0;ebp -= 1){
        rax = *(rbx + 8)
        eax = *rax
        if(*rbx < eax){
        explode_bomb()  
        }
        rbx = *(rbx + 8)
    }
-------------------------------------------------------------

    return 0;

}

C_like代码:

// 确保六个数都不相同  (并且保证都小于7) 
//          1 -> 2~5     
//          2 -> 3~5 
//          ...
void check_six_numbers(int * arr){
    int i = 0;

    while(i < 5){
        if(arr[i] > 6){
            explode_bomb();
        } 
        i++;
        check_array(arr, i);
    }
}

void check_array(int * arr, int n){
    for(int i = n;i < 5;i++){
        if(arr[i] == arr[n - 1]){
            explode_bomb();
        }
    }
}

typedef struct {
    int val;
    Node* node_next;
}Node;

void phase_6(char * output){
    int array[6];
    Node* Node_array[6];
    read_six_numbers(output, array);
    
    check_six_numbers(array);

    // 调整数组元素
    for(int i = 0;i < 6;i++){
        array[i] = 7 - array[i];
    }

    for(int i = 0;i < 6;i++){
        int elem = array[i];
        Node* head = (Node*)0x6032d0;
        if(elem > 1){
            for(int j = 1;j != elem;j++){
                head = head->node_next;
            }
        }
        Node_array[i] = head;
    }

    for(int i = 0;i < 5;i++){
        Node_array[i]->node_next = Node_array[i + 1];
    }
    Node_array[5]->node_next = nullptr;
    

    for(int i = 0;i < 5;i++){
        if(Node_array[i]->val < Node_array[i]->node_next->val){
            explode_bomb();
        }
    }


}

 

完成情况: 

Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Border relations with Canada have never been better.
Phase 1 defused. How about the next one?
1 2 4 8 16 32
That's number 2.  Keep going!
0 207
Halfway there!
1 0xcf
So you got that one.  Try this one.
ionefg
Good work!  On to the next...
4 3 2 1 6 5
Congratulations! You've defused the bomb!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值