2値化爆弾解除の記録
学校からバイナリーボムの宿題が出され、自分で解体する作戦を確認しながら、合計2~3日かけて完成したものを解体していく。解体するときは、先に行った人の経験談を見ると上達が早い気がするので、まだ初心者の私でも、参考までに載せておきたいと思います。
の前に書いてください。
<ブロッククオートhttps://www.cnblogs.com/liqiuhao/p/7624880.html和https://blog.csdn.net/the_v_/article/details/46842337/这两位大佬的无私奉献 のおかげで、私の爆弾発言は、この2つの解体の参考になりました。
0.gdbのブレークポイント
特に心配だったのは、爆弾を解除する前に爆発してしまうことです。gdbデバッグでブレークポイントを設定できることは知っていても、その方法がまだ理解できていませんでした。そこで、ブレークポイントの設定と結果をトップで実演し、爆発を恐れず安心して爆弾を爆発させることができるようにしますhh
どのように私はスキップした爆弾のファイルに入るには、爆弾が話すか、ステップバイステップのドキュメントか何かを参照する必要があります前に解体する必要があります。
では、爆弾のある場所までcdして、gdbデバッグだとします。
(@の前に学校番号があるので、表示されない) gdb bombと直接入力(または爆弾の名前)
すると、このようになり、gdbコマンドを直接入力できるようになります。
break *0x401751(爆弾があるアドレス、watch callq xxxxxx<explode_bomb> )と入力してEnterすると、ブレークポイントが設定されたことが表示されます。
その後、run と入力すれば爆弾の実行が開始され、もし間違った結果を入力して爆弾が爆発した場合は、次のように表示されます。
これでブレークポイントが有効になりました。この時点で、gdbのデバッグを続けるか(データを見るにはrunかx/s 0xxxxxxx)、qをタイプして終了してください。終了した後、再びgdb bombをするときには、ブレークポイントをリセットすることを忘れないでください。ブレークポイントが爆弾の前に設定されている場合、c(continue)を入力しない、または実行を継続することは爆発です。
さて、いよいよ正式に爆弾の信管を外す作業を開始します
*csapp 3rd P120: %r(e)di 第1引数; %r(e)si 第2引数; %r(e)dx 第3引数; %r(e)cx 第4引数、%eax 関数の戻り値です。後で使うかもしれません。
1. Phase1 文字列比較
00000000000000400f90 <phase_1>:
400f90: 48 83 ec 08 sub $0x8,%rsp //current input
400f94: be 50 27 40 00 mov
$0x402750
,%esi // take the contents of 0x402750, as the second argument
400f99: e8 da 04 00 00 callq 401478 <strings_not_equal>// found a call to a function that compares two strings
400f9e: 85 c0 test %eax,%eax
400fa0: 74 05 je 400fa7 <phase_1+0x17>//return value is not 0, googled: test themselves, plus je, is to compare is not 0
400fa2: e8 aa 07 00 00 callq 401751 <explode_bomb>//or blow up
400fa7: 48 83 c4 08 add $0x8,%rsp
400fab: c3 retq
strings_not_equal (文字列が同じ場合に返されるものだけを調べました)
00000000000000401478 <strings_not_equal>:
401478: 41 54 push %r12
40147a: 55 push %rbp
40147b: 53 push %rbx
40147c: 48 89 fb mov %rdi,%rbx //rbx=first parameter address: input
40147f: 48 89 f5 mov %rsi,%rbp// rbp=second parameter address: address
401482: e8 d4 ff ff ff callq 40145b <string_length>
401487: 41 89 c4 mov %eax,%r12d // r12d input string length
40148a: 48 89 ef mov %rbp,%rdi
40148d: e8 c9 ff ff ff callq 40145b <string_length>
401492: ba 01 00 00 00 mov $0x1,%edx
401497: 41 39 c4 cmp %eax,%r12d //compare length of two strings
40149a: 75 3f jne 4014db <strings_not_equal+0x63>
40149c: 0f b6 03 movzbl (%rbx),%eax//equal, extract first character of input
40149f: 84 c0 test %al,%al
4014a1: 74 25 je 4014c8 <strings_not_equal+0x50>//compare if input is 0 (end of string), end jump
4014a3: 3a 45 00 cmp 0x0(%rbp),%al//Didn't end, compare the first character of the two strings
4014a6: 74 0a je 4014b2 <strings_not_equal+0x3a>//same jump... .4b2
4014a8: eb 25 jmp 4014cf <strings_not_equal+0x57>
4014aa: 3a 45 00 cmp 0x0(%rbp),%al///From . ...4bf jump here, look out for this loop block Start loop to compare one by one
4014ad: 0f 1f 00 nopl (%rax)
4014b0: 75 24 jne 4014d6 <strings_not_equal+0x5e>
4014b2: 48 83 c3 01 add $0x1,%rbx///First character same to here
4014b6: 48 83 c5 01 add $0x1,%rbp//Second character
4014ba: 0f b6 03 movzbl (%rbx),%eax
4014bd: 84 c0 test %al,%al
4014bf: 75 e9 jne 4014aa <strings_not_equal+0x32>//again, is it the end
4014c1: ba 00 00 00 00 mov $0x0,%edx//Compare to the end of the string, edx=0
4014c6: eb 13 jmp 4014db <strings_not_equal+0x63>//jump... .4db
4014c8: ba 00 00 00 00 mov $0x0,%edx
4014cd: eb 0c jmp 4014db <strings_not_equal+0x63>
4014cf: ba 01 00 00 00 mov $0x1,%edx
4014d4: eb 05 jmp 4014db <strings_not_equal+0x63>
4014d6: ba 01 00 00 00 mov $0x1,%edx
4014db: 89 d0 mov %edx,%eax//If all are equal, return value is 0
4014dd: 5b pop %rbx
4014de: 5d pop %rbp
4014df: 41 5c pop %r12
4014e1: c3 retq
解析の結果、0x402750が目的の文字列であることがわかったので、(gdb) x/s 0x402750 で文字列をチェックします。私の家からロシアが見える!" ロシアと中国の友好は長く続くだろう hhhh
2.第2期シリーズ
00000000000000400fac <phase_2>:0 1 1 2 3 5
400fac: 55 push %rbp
400fad: 53 push %rbx
400fae: 48 83 ec 28 sub $0x28,%rsp
400fb2: 48 89 e6 mov %rsp,%rsi
400fb5: e8 cd 07 00 00 callq 401787 <read_six_numbers>// look at the name anyway to know read in six numbers ... Look closely at the function is too big head ...
400fba: 83 3c 24 00 cmpl $0x0,(%rsp)//rsp point to the first number, you can just lose a string of numbers gdb take a look, anyway, not afraid to blow hahaha
400fbe: 75 07 jne 400fc7 <phase_2+0x1b> // and 0 than, not equal to blow up (ac+1b=c7)
400fc0: 83 7c 24 04 01 cmpl $0x1,0x4(%rsp)//rsp+4 //second number, compare with 1
400fc5: 74 21 je 400fe8 <phase_2+0x3c> //not equal explosion, equal jump e8
400fc7: e8 85 07 00 00 callq 401751 <explode_bomb>
400fcc: eb 1a jmp 400fe8 <phase_2+0x3c>
400fce: 8b 43 f8 mov -0x8(%rbx),%eax//eax=rbx first two digits
400fd1: 03 43 fc add -0x4(%rbx),%eax//eax=eax+eax previous number
400fd4: 39 03 cmp %eax,(%rbx)//compare whether rbx is equal to the sum of the first two numbers
400fd6: 74 05 je 400fdd <phase_2+0x31>equal jump dd otherwise blow
400fd8: e8 74 07 00 00 callq 401751 <explode_bomb>
400fdd: 48 83 c3 04 add $0x4,%rbx//rbx shift back one
400fe1: 48 39 eb cmp %rbp,%rbx // whether rbx is out of range by 6
400fe4: 75 e8 jne 400fce <phase_2+0x22> //rbx not out of range, loop ce
400fe6: eb 0c jmp 400ff4 <phase_2+0x48> //exceeded, jump f4 , end
400fe8: 48 8d 5c 24 08 lea 0x8(%rsp),%rbx //rbx points to third number
400fed: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp//rbp points to rsp+24, i.e. the data after the sixth digit
400ff2: eb da jmp 400fce <phase_2+0x22> skip ce
400ff4: 48 83 c4 28 add $0x28,%rsp
400ff8: 5b pop %rbx
400ff9: 5d pop %rbp
400ffa: c3 retq
ループ本体の外側で比較すると、最初の数=0、2番目の数=1であることがわかる。ループは配列 a[i+2] == a[i+1]+a[i] を判断するために使用されるので、解答配列が導かれることになります。0 1 1 2 3 5
3. フェーズ3スイッチ
00000000000000400ffb <phase_3>:
400ffb: 48 83 ec 18 sub $0x18,%rsp
400fff: 4c 8d 44 24 0c lea 0xc(%rsp),%r8///3rd input
401004: 48 8d 4c 24 07 lea 0x7(%rsp),%rcx//2nd input
401009: 48 8d 54 24 08 lea 0x8(%rsp),%rdx///First input
40100e: be 96 27 40 00 mov $0x402796,%esi//move the input here
401013: b8 00 00 00 00 mov $0x0,%eax
401018: e8 93 fc ff ff callq 400cb0 <__isoc99_sscanf@plt>
40101d: 83 f8 02 cmp $0x2,%eax //eax returns the number of inputs
401020: 7f 05 jg 401027 <phase_3+0x2c> //greater than 2 jump 1027, otherwise blow. So greater than two inputs
401022: e8 2a 07 00 00 callq 401751 <explode_bomb>
401027: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp) //rdx and 7
40102c: 0f 87 fc 00 00 00 ja 40112e <phase_3+0x133>//greater than 7, jump 112e bomb , so rdx is less than 7
401032: 8b 44 24 08 mov 0x8(%rsp),%eax
401036: ff 24 c5 a0 27 40 00 jmpq
*0x4027a0
(,%rax,8)//with switch jump Base address 40103d
前のアドレスを見てみると、オフセットを加えた後にジャンプするアドレスで、0を入力することにしたので、40103dにジャンプしています
40103d: b8 71 00 00 00 mov $0x71,%eax //eax=71H
401042: 81 7c 24 0c 6e 03 00 cmpl $0x36e,0xc(%rsp) //third digit=878
401049: 00
40104a: 0f 84 e8 00 00 00 je 401138 <phase_3+0x13d>
401050: e8 fc 06 00 00 callq 401751 <explode_bomb>
401055: b8 71 00 00 00 mov $0x71,%eax
40105a: e9 d9 00 00 00 jmpq 401138 <phase_3+0x13d>//jump . .1138
40105f: b8 64 00 00 00 mov $0x64,%eax
401064: 81 7c 24 0c fd 02 00 cmpl $0x2fd,0xc(%rsp)
40106b: 00
40106c: 0f 84 c6 00 00 00 je 401138 <phase_3+0x13d>
401072: e8 da 06 00 00 callq 401751 <explode_bomb>
401077: b8 64 00 00 00 mov $0x64,%eax
40107c: e9 b7 00 00 00 jmpq 401138 <phase_3+0x13d>
401081: b8 61 00 00 00 mov $0x61,%eax
401086: 81 7c 24 0c c8 00 00 cmpl $0xc8,0xc(%rsp)
40108d: 00
40108e: 0f 84 a4 00 00 00 je 401138 <phase_3+0x13d>
401094: e8 b8 06 00 00 callq 401751 <explode_bomb>
401099: b8 61 00 00 00 mov $0x61,%eax
40109e: e9 95 00 00 00 jmpq 401138 <phase_3+0x13d>
4010a3: b8 63 00 00 00 mov $0x63,%eax
4010a8: 81 7c 24 0c 76 02 00 cmpl $0x276,0xc(%rsp)
4010af: 00
4010b0: 0f 84 82 00 00 00 je 401138 <phase_3+0x13d>
4010b6: e8 96 06 00 00 callq 401751 <explode_bomb>
4010bb: b8 63 00 00 00 mov $0x63,%eax
4010c0: eb 76 jmp 401138 <phase_3+0x13d>
4010c2: b8 78 00 00 00 mov $0x78,%eax
4010c7: 81 7c 24 0c df 00 00 cmpl $0xdf,0xc(%rsp)
4010ce: 00
4010cf: 74 67 je 401138 <phase_3+0x13d>
4010d1: e8 7b 06 00 00 callq 401751 <explode_bomb>
4010d6: b8 78 00 00 00 mov $0x78,%eax
4010db: eb 5b jmp 401138 <phase_3+0x13d>
4010dd: b8 72 00 00 00 mov $0x72,%eax
4010e2: 81 7c 24 0c f9 02 00 cmpl $0x2f9,0xc(%rsp)
4010e9: 00
4010ea: 74 4c je 401138 <phase_3+0x13d>
4010ec: e8 60 06 00 00 callq 401751 <explode_bomb>
4010f1: b8 72 00 00 00 mov $0x72,%eax
4010f6: eb 40 jmp 401138 <phase_3+0x13d>
4010f8: b8 69 00 00 00 mov $0x69,%eax
4010fd: 81 7c 24 0c 73 03 00 cmpl $0x373,0xc(%rsp)
401104: 00
401105: 74 31 je 401138 <phase_3+0x13d>
401107: e8 45 06 00 00 callq 401751 <explode_bomb>
40110c: b8 69 00 00 00 mov $0x69,%eax
401111: eb 25 jmp 401138 <phase_3+0x13d>
401113: b8 75 00 00 00 mov $0x75,%eax
401118: 81 7c 24 0c a0 02 00 cmpl $0x2a0,0xc(%rsp)
40111f: 00
401120: 74 16 je 401138 <phase_3+0x13d>
401122: e8 2a 06 00 00 callq 401751 <explode_bomb>
401127: b8 75 00 00 00 mov $0x75,%eax
40112c: eb 0a jmp 401138 <phase_3+0x13d>
40112e: e8 1e 06 00 00 callq 401751 <explode_bomb>
401133: b8 63 00 00 00 mov $0x63,%eax
401138: 3a 44 24 07 cmp 0x7(%rsp),%al // go here and compare the second number with al (eax lower 8 bits) which is 0x71: 113--ASCII(q)
40113c: 74 05 je 401143 <phase_3+0x148>
40113e: e8 0e 06 00 00 callq 401751 <explode_bomb>
401143: 48 83 c4 18 add $0x18,%rsp
401147: c3 retq
ノックレベルが長く感じられる?長いのはいいんだけど...。ああの理解を参照してください... 第四再帰は、私が吐いた...
2回目の入力でぐずぐず・・・。なんで間違うんだろうと思いながら113を入力し続けたら、どんどん吹っ飛んでいって、ついに格納されているアドレスのデータ型を見に行ったら...。
なんと、2つ目は実は文字なんです(実は冒頭でヒントが出ていて、0x7(%rsp)と0x8(%rsp)、1バイトはもちろんcharなんですが・・・。しかし、私はバカだ...) そして、ASCIIコードを調べて思い出したのが、3つ目の答えです。0 q 878
4. Phase4 再帰
0000000000000040117b <phase_4>:
40117b: 48 83 ec 18 sub $0x18,%rsp
40117f: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx //second input
401184: 48 8d 54 24 08 lea 0x8(%rsp),%rdx //first input
401189: be 6d 2a 40 00 mov $0x402a6d,%esi
40118e: b8 00 00 00 00 mov $0x0,%eax
401193: e8 18 fb ff ff callq 400cb0 <__isoc99_sscanf@plt>
401198: 83 f8 02 cmp $0x2,%eax
40119b: 75 07 jne 4011a4 <phase_4+0x29>//not equal, bomb so enter two numbers
40119d: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp)
4011a2: 76 05 jbe 4011a9 <phase_4+0x2e> //the first number is less than or equal to 14, jump a9
4011a4: e8 a8 05 00 00 callq 401751 <explode_bomb>
4011a9: ba 0e 00 00 00 mov $0xe,%edx //edx=14
4011ae: be 00 00 00 00 mov $0x0,%esi //esi=0
4011b3: 8b 7c 24 08 mov 0x8(%rsp),%edi //edi=first input
4011b7: e8 8c ff ff ff callq 401148 <func4>
4011bc: 83 f8 25 cmp $0x25,%eax
4011bf: 75 07 jne 4011c8 <phase_4+0x4d> // return must be 0x25=37
4011c1: 83 7c 24 0c 25 cmpl $0x25,0xc(%rsp) //second number is 37
4011c6: 74 05 je 4011cd <phase_4+0x52>
4011c8: e8 84 05 00 00 callq 401751 <explode_bomb>
4011cd: 48 83 c4 18 add $0x18,%rsp
4011d1: c3 retq
0000000000401148 <func4>:// three arguments, (edi=input, rsi,rdx)
401148: 53 push %rbx
401149: 89 d0 mov %edx,%eax //eax=14
40114b: 29 f0 sub %esi,%eax //eax=eax-0=14
40114d: 89 c3 mov %eax,%ebx //ebx=14
40114f: c1 eb 1f shr $0x1f,%ebx //logical right shift 31 bits 14>>31=0
401152: 01 d8 add %ebx,%eax //eax=eax+0=14
401154: d1 f8 sar %eax //eax arithmetic shift right eax=7
401156: 8d 1c 30 lea (%rax,%rsi,1),%ebx //ebx=rsi+rax=0+14=14
401159: 39 fb cmp %edi,%ebx
40115b: 7e 0c jle 401169 <func4+0x21> //14<=Enter first number Skip 69
40115d: 8d 53 ff lea -0x1(%rbx),%edx //Input first number<14 edx=rbx-1=13
401160: e8 e3 ff ff ff callq 401148 <func4> //recursive
401165: 01 d8 add %ebx,%eax //eax=eax+ebx=14+recursive return
401167: eb 10 jmp 401179 <func4+0x31>//end
401169: 89 d8 mov %ebx,%eax //eax=14
40116b: 39 fb cmp %edi,%ebx
40116d: 7d 0a jge 401179 <func4+0x31> //14>=Enter first number Skip 79,end. If 14 is entered, then return 14
40116f: 8d 73 01 lea 0x1(%rbx),%esi //enter first number>14 esi=rbx+1=14+1
401172: e8 d1 ff ff ff callq 401148 <func4>//recursive
401177: 01 d8 add %ebx,%eax//eax=eax+ebx return
401179: 5b pop %rbx
40117a: c3 retq
int digui(int edi, int rsi, int rdx)
{
int eax = rdx;
int ebx = eax;
eax = eax - rsi;
ebx = ebx >> 31;
eax = ebx + eax;
eax = eax / 2;
ebx = rsi + eax;
if (ebx <= edi)
{
eax = ebx;
if (ebx >= edi)
return eax;
else
{
rsi = ebx + 1;
return digui(edi, rsi, rdx) + ebx;
}
}
else
{
rdx = ebx - 1;
return digui(edi, rsi, rdx) + ebx;
}
}
みんな、ごめんね・・・。私はこの質問で死亡した... 何からこの再帰を理解していない夜を見た...
最初の数字に範囲があり、2番目の数字が決まっているので、暴力的に爆弾を解除しています...。これからも研究を続けて、新しいものを作ってみようと思います...。
網羅的なリストの答えは、10 37
wow it worked it worked, reread func4 and wrote it in C as follows.
000000000000004011d2 <phase_5>:
4011d2: 48 83 ec 18 sub $0x18,%rsp
4011d6: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx// Second number
4011db: 48 8d 54 24 08 lea 0x8(%rsp),%rdx///First number
4011e0: be 6d 2a 40 00 mov $0x402a6d,%esi //input put here
4011e5: b8 00 00 00 00 mov $0x0,%eax
4011ea: e8 c1 fa ff ff callq 400cb0 <__isoc99_sscanf@plt>
4011ef: 83 f8 01 cmp $0x1,%eax
4011f2: 7f 05 jg 4011f9 <phase_5+0x27> //input parameters greater than 1
4011f4: e8 58 05 00 00 callq 401751 <explode_bomb>
4011f9: 8b 44 24 08 mov 0x8(%rsp),%eax //eax=first number
4011fd: 83 e0 0f and $0xf,%eax //eax=fourth digit after the first number
401200: 89 44 24 08 mov %eax,0x8(%rsp) //0x8(rsp)=last four bits
401204: 83 f8 0f cmp $0xf,%eax
401207: 74 2c je 401235 <phase_5+0x63> //if the last four bits of the first number are all 1s blow up
401209: b9 00 00 00 00 mov $0x0,%ecx //ecx=0
40120e: ba 00 00 00 00 mov $0x0,%edx //edx=0
401213: 83 c2 01 add $0x1,%edx //edx=1 Addition times
401216: 48 98 cltq
401218: 8b 04 85 e0 27 40 00 mov
0x4027e0
(,%rax,4),%eax //gdb look at 0x4027e0 eax=base address plus 4*lower four bits of the first number
<イグ
0から14まで入力した結果は上記のようになり、10を入力した場合は37が返されます
5. Phase5 配列
40121f: 01 c1 add %eax,%ecx //ecx=ecx+eax which means the result of the read is cumulative
401221: 83 f8 0f cmp $0xf,%eax //eax!=f read out not f, keep looping
401224: 75 ed jne 401213 <phase_5+0x41> //not f, skip 213
401226: 89 44 24 08 mov %eax,0x8(%rsp)//read out as offset for next jump
40122a: 83 fa 0f cmp $0xf,%edx //edx=15 must be added 15 times, i.e., ensure that f is read on the fifteenth
40122d: 75 06 jne 401235 <phase_5+0x63>
40122f: 3b 4c 24 0c cmp 0xc(%rsp),%ecx //rsp+12=ecx The second number entered is equal to the accumulation of fifteen numbers
401233: 74 05 je 40123a <phase_5+0x68>
401235: e8 17 05 00 00 callq 401751 <explode_bomb>
40123a: 48 83 c4 18 add $0x18,%rsp
40123e: c3 retq
このアドレスの後に、以下のように0~fの16個の数字がナンバリングされ、内容が表示されます。
<テーブル 0 1 2 3 4 5 6 7 8 9 a b c d e f a 2 e 7 8 c f b 0 4 1 d 3 9 6 5
0000000000000040123f <phase_6>:
40123f: 41 56 push %r14
401241: 41 55 push %r13
401243: 41 54 push %r12
401245: 55 push %rbp
401246: 53 push %rbx
401247: 48 83 ec 50 sub $0x50,%rsp
40124b: 49 89 e5 mov %rsp,%r13
40124e: 48 89 e6 mov %rsp,%rsi
401251: e8 31 05 00 00 callq 401787 <read_six_numbers>//read six numbers
401256: 49 89 e6 mov %rsp,%r14
401259: 41 bc 00 00 00 00 mov $0x0,%r12d
40125f: 4c 89 ed mov %r13,%rbp///loop body
401262: 41 8b 45 00 mov 0x0(%r13),%eax
401266: 83 e8 01 sub $0x1,%eax
401269: 83 f8 05 cmp $0x5,%eax
40126c: 76 05 jbe 401273 <phase_6+0x34>// determine if input is less than or equal to six (eax-1 is less than or equal to 5)
40126e: e8 de 04 00 00 callq 401751 <explode_bomb>
401273: 41 83 c4 01 add $0x1,%r12d//r12 add one and six compare
401277: 41 83 fc 06 cmp $0x6,%r12d
40127b: 74 21 je 40129e <phase_6+0x5f>//equal Jump 9e
40127d: 44 89 e3 mov %r12d,%ebx//r12 1~5
401280: 48 63 c3 movslq %ebx,%rax//loop body
401283: 8b 04 84 mov (%rsp,%rax,4),%eax//eax=base address plus 4*r12
401286: 39 45 00 cmp %eax,0x0(%rbp)
401289: 75 05 jne 401290 <phase_6+0x51>//Current input (base address) and eax (offset) compare to be different
40128b: e8 c1 04 00 00 callq 401751 <explode_bomb>
401290: 83 c3 01 add $0x1,%ebx//ebx+1 see ebx as number after current input
401293: 83 fb 05 cmp $0x5,%ebx
401296: 7e e8 jle 401280 <phase_6+0x41>//ebx is less than or equal to 5, jump 80, inner loop, compare current number and all numbers after it are not the same
401298: 49 83 c5 04 add $0x4,%r13//base address add 4, move current number back one
40129c: eb c1 jmp 40125f <phase_6+0x20>//jump 5f, outer loop, traverse six numbers
40129e: 48 8d 74 24 18 lea 0x18(%rsp),%rsi///compared the input six numbers are not the same rsi as the input six numbers after the boundary address
4012a3: 4c 89 f0 mov %r14,%rax //rax the address of the first digit
4012a6: b9 07 00 00 00 mov $0x7,%ecx
4012ab: 89 ca mov %ecx,%edx//loop body
4012ad: 2b 10 sub (%rax),%edx
4012af: 89 10 mov %edx,(%rax)//
正直なところ、この爆弾を長時間読んでいても、ちょっとめまいがします...。下4桁しか考慮しないのだから、入力はすべて0-fに限定しよう、その方が楽だ。
このループは、私にはかなり複雑に見えますが...。説明しますと... 例えば、最初に入力した数字が0なので、表に従って、table[0]=aを読み出すと、累積0+aがaになり、次の入力がa、2回目のループでは、table[a]=1を読み出すと、累積a+1=bとなり、次の入力が1、3回目ではtable[1]=2と読み出し、累積b+2、次の 次入力が2 ...... と、なっているのですが、このように、ループが複雑になります。
要件を見てください。15番目に読み出されるのはfで、次に後ろに:
fを読むと、前のものは6、6を読むと、前のものはe、eを読むと、...となります。
f-6-e-2-1-a-0-8-4-9-d-b-7-3-c-5-f... という順序を導き出す。ループを開始する。
fから前方へ15を数えると、最初の読みはcなので、最初の入力は5となるはずです。
つまり、上記のfからcまでのシーケンスを追加するか、0から16までのシーケンスから5を引いたものを計算します(fのシーケンスは数字を読む時間がなくスキップされます)。
結果:5 115
6. フェーズ6
401325: bd 05 00 00 00 mov $0x5,%ebp
40132a: 48 8b 43 08 mov 0x8(%rbx),%rax//loop body
40132e: 8b 00 mov (%rax),%eax
401330: 39 03 cmp %eax,(%rbx)
401332: 7d 05 jge 401339 <phase_6+0xfa>//(rbx) is greater than or equal to ((rbx+8))
401334: e8 18 04 00 00 callq 401751 <explode_bomb>
401339: 48 8b 5b 08 mov 0x8(%rbx),%rbx//rbx=(rbx+8)
40133d: 83 ed 01 sub $0x1,%ebp//ebp-1
401340: 75 e8 jne 40132a <phase_6+0xeb>//non-zero, jump 2a
401342: 48 83 c4 50 add $0x50,%rsp
401346: 5b pop %rbx
401347: 5d pop %rbp
401348: 41 5c pop %r12
40134a: 41 5d pop %r13
40134c: 41 5e pop %r14
40134e: c3 retq
上の段落は大きなループで、おそらく1〜6が6つのアドレスに対応する関係が確立されており、あまり気にせずgdbで直接見ることができます(この段落はあまりじっくり見ていません...)。
000000000000004018ef <phase_defused>:
4018ef: 48 83 ec 78 sub $0x78,%rsp
4018f3: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4018fa: 00 00
4018fc: 48 89 44 24 68 mov %rax,0x68(%rsp)
401901: 31 c0 xor %eax,%eax
401903: bf 01 00 00 00 mov $0x1,%edi
401908: e8 38 fd ff ff callq 401645 <send_msg>
40190d: 83 3d a8 2e 20 00 06 cmpl $0x6,0x202ea8(%rip) # 6047bc <num_input_strings>
401914: 75 6d jne 401983 <phase_defused+0x94>
401916: 4c 8d 44 24 10 lea 0x10(%rsp),%r8
40191b: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
401920: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
401925: be b7 2a 40 00 mov $0x402ab7,%esi
40192a: bf d0 48 60 00 mov $0x6048d0,%edi
40192f: b8 00 00 00 00 mov $0x0,%eax
401934: e8 77 f3 ff ff callq 400cb0 <__isoc99_sscanf@plt>
401939: 83 f8 03 cmp $0x3,%eax//Must enter three quantities
40193c: 75 31 jne 40196f <phase_defused+0x80>//jump 6f,find jump out secret_phase call, so the above conditions must be met, and the next program is the hidden bomb entrance
40193e: be c0 2a 40 00 mov $0x402ac0,%esi //hide
401943: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
401948: e8 2b fb ff ff callq 401478 <strings_not_equal>// and a fixed address to compare strings, then the address is likely to be the password
40194d: 85 c0 test %eax,%eax
40194f: 75 1e jne 40196f <phase_defused+0x80>
401951: bf 18 29 40 00 mov $0x402918,%edi
401956: e8 65 f2 ff ff callq 400bc0 <puts@plt>
40195b: bf 40 29 40 00 mov $0x402940,%edi
401960: e8 5b f2 ff ff callq 400bc0 <puts@plt>
401965: b8 00 00 00 00 mov $0x0,%eax
40196a: e8 1e fa ff ff callq 40138d <secret_phase>
40196f: bf 78 29 40 00 mov $0x402978,%edi
401974: e8 47 f2 ff ff callq 400bc0 <puts@plt>
401979: bf a8 29 40 00 mov $0x4029a8,%edi
40197e: e8 3d f2 ff ff callq 400bc0 <pts@plt>
401983: 48 8b 44 24 68 mov 0x68(%rsp),%rax
401988: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
40198f: 00 00
401991: 74 05 je 401998 <phase_defused+0xa9>
401993: e8 48 f2 ff ff callq 400be0 <__stack_chk_fail@plt>
401998: 48 83 c4 78 add $0x78,%rsp
40199c: c3 retq
40199d: 0f 1f 00 nopl (%rax)
ノックロングノックロングノックロング... 必死で長く...
最後の段落で、見つけるために。7 - 番号の結果の番号を入力してください - 対応するアドレス - 対応する番号 - サイズの配置 - 逆入力
大きなループの中で定数アドレスが何度も登場し、その後gdbが混乱することに注意してください
1 2 3 4 5 6 と直接入力したら結果がおかしかったので、breakpoint1 と表示されて爆弾が爆発し、その後自動的に gdb に移動したので、直接デバッグすることが出来ました。
rspの中は処理した数値とアドレスの関係、rdxの中はアドレスメモリからのデータです。
対応関係を導き出すための整理
6 ---604360 ---1bf
5--604350 ---0e1
4 ---604340 ---05f
3 ---604330 ---2e1
2 ---604320 ---35c
1--604310 ---231
sort 35c(2)>2e1(3)>231(1)>1bf(6)>0e1(5)>05f(4)
収量入力 5 4 6 1 2 3
7. 秘密の爆弾 再帰的
0000000000000040138d <secret_phase>:
40138d: 53 push %rbx
40138e: e8 36 04 00 00 callq 4017c9 <read_line>
401393: ba 0a 00 00 00 mov $0xa,%edx
401398: be 00 00 00 00 mov $0x0,%esi
40139d: 48 89 c7 mov %rax,%rdi
4013a0: e8 eb f8 ff ff callq 400c90 <strtol@plt>
4013a5: 48 89 c3 mov %rax,%rbx
4013a8: 8d 40 ff lea -0x1(%rax),%eax
4013ab: 3d e8 03 00 00 cmp $0x3e8,%eax
4013b0: 76 05 jbe 4013b7 <secret_phase+0x2a>//read -1 less than or equal to 3e8
4013b2: e8 9a 03 00 00 callq 401751 <explode_bomb>
4013b7: 89 de mov %ebx,%esi //parameter two
4013b9: bf 30 41 60 00 mov
$0x604130
,%edi // parameter one
4013be: e8 8c ff ff ff callq 40134f <fun7>
4013c3: 85 c0 test %eax,%eax
4013c5: 74 05 je 4013cc <secret_phase+0x3f>// return must be zero, so my main concern in fun7 is how to return 0
4013c7: e8 85 03 00 00 callq 401751 <explode_bomb>
4013cc: bf 70 27 40 00 mov $0x402770,%edi
4013d1: e8 ea f7 ff ff callq 400bc0 <puts@plt>
4013d6: e8 14 05 00 00 callq 4018ef <phase_defused>
4013db: 5b pop %rbx
4013dc: c3 retq
4013dd: 0f 1f 00 nopl (%rax)
secret_phaseの呼び出し先を探したところ、phase_defusedにあることがわかりました。出現するアドレスに着目。
きっとパスワードがある
実行開始前のデバッグなので、入力は何もなかったのですが、入力比較の基準値が、2つの整数+文字列でした。2つの整数+DrEvil.という文字列の答えで、何かの爆弾を解除するときだとわかる。私のは4番目の爆弾で入力された。
0000000000000040134f <fun7>:
40134f: 48 83 ec 08 sub $0x8,%rsp
401353: 48 85 ff test %rdi,%rdi
401356: 74 2b je 401383 <fun7+0x34>//edi is not 0
401358: 8b 17 mov (%rdi),%edx
40135a: 39 f2 cmp %esi,%edx
40135c: 7e 0d jle 40136b <fun7+0x1c>//24H is less than or equal to input, jump 6b
40135e: 48 8b 7f 08 mov 0x8(%rdi),%rdi
401362: e8 e8 ff ff ff ff callq 40134f <fun7>
401367: 01 c0 add %eax,%eax
401369: eb 1d jmp 401388 <fun7+0x39>
40136b: b8 00 00 00 00 mov $0x0,%eax//eax=0, target appears!
401370: 39 f2 cmp %esi,%edx
401372: 74 14 je 401388 <fun7+0x39>//end of jump, then the condition must be met, i.e. input=24H=36
401374: 48 8b 7f 10 mov 0x10(%rdi),%rdi
401378: e8 d2 ff ff ff callq 40134f <fun7>
40137d: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
401381: eb 05 jmp 401388 <fun7+0x39>
401383: b8 ff ff ff ff mov $0xffffffff,%eax
401388: 48 83 c4 08 add $0x8,%rsp
40138c: c3 retq
edi=24H。
func7 懸念事項:0を返す
0000000000000040134f <fun7>:
40134f: 48 83 ec 08 sub $0x8,%rsp
401353: 48 85 ff test %rdi,%rdi
401356: 74 2b je 401383 <fun7+0x34>//edi is not 0
401358: 8b 17 mov (%rdi),%edx
40135a: 39 f2 cmp %esi,%edx
40135c: 7e 0d jle 40136b <fun7+0x1c>//24H is less than or equal to input, jump 6b
40135e: 48 8b 7f 08 mov 0x8(%rdi),%rdi
401362: e8 e8 ff ff ff ff callq 40134f <fun7>
401367: 01 c0 add %eax,%eax
401369: eb 1d jmp 401388 <fun7+0x39>
40136b: b8 00 00 00 00 mov $0x0,%eax//eax=0, target appears!
401370: 39 f2 cmp %esi,%edx
401372: 74 14 je 401388 <fun7+0x39>//end of jump, then the condition must be met, i.e. input=24H=36
401374: 48 8b 7f 10 mov 0x10(%rdi),%rdi
401378: e8 d2 ff ff ff callq 40134f <fun7>
40137d: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
401381: eb 05 jmp 401388 <fun7+0x39>
401383: b8 ff ff ff ff mov $0xffffffff,%eax
401388: 48 83 c4 08 add $0x8,%rsp
40138c: c3 retq
そして、24H=36という答えを入力します。
8. 最終結果
最後はふりかけ!
関連
-
Uncaught SyntaxError: 位置1でJSONの予期しないトークンoは、問題が解決されました。
-
pandas Tutorial [4] データフレームフィルタリングデータ !
-
未定義のエラーのプロパティ 'replace' を読み取ることができません。
-
raise NotImplementedError
-
クラスタへのJava apiアクセス(Kerberos認証が通らない)
-
Angular.js Unknownプロバイダエラー
-
R言語ファイル読み込みエラー
-
ValueErrorの解決策:解凍する値が足りない(期待値2、取得値1)。
-
ansible error resolution:UNREACHABLE sshでホストへの接続に失敗しました。
-
ASP.NET MVCでsessionIDの解が変わり続ける。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
C++におけるconst_castの役割と理由
-
デバッグアサーションに失敗しました
-
プログラム ld の解決策の 1 つが 1 の終了ステータスを返した
-
Uncaught TypeError: Node' の 'removeChild' の実行に失敗しました: 1 つの引数が必要ですが、0 つしかありません。
-
ArrayAdapterの外観は、リソースIDがTextViewである必要がある問題について
-
Rollup.js|solve the package react project error ReferenceError: process is not defined.
-
スーパークラス「javax.servlet.http.HttpServlet」がJavaビルドパスソリューションで見つかりませんでした。
-
この宣言には、ストレージクラスまたはタイプ指定子がありません。この警告は何を意味するのですか?
-
PY 実行プログラム・プロンプト "TypeError: unsupported operand type(s) for %: 'NoneType' and 'tuple'" ソリューション・インサイト
-
Androidアプリケーション開発 - ビープ音とバイブレーションによる警告の実装