Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rustで作るi386エミュレータ

 Rustで作るi386エミュレータ

Hitoshi Kurokawa

December 21, 2019
Tweet

More Decks by Hitoshi Kurokawa

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • ࠇ઒ ਔ @krhitoshi • ݸਓࣄۀओ Next SeeD •

    αʔό؅ཧ • γεςϜ։ൃ • ޷͖ͳݴޠ: Ruby
  2. ௿ϨΠϠʹڵຯΛ࣋ͬͨ • Turing Complete FM (ϙουΩϟετ)
 ϗετ: Rui Ueyama͞Μ
 https://turingcomplete.fm/

    • ήετ: Gauche Scheme࡞ऀ ઒߹࢙࿕͞Μ
 Gaucheͷ಺෦࣮૷ɺݴޠॲཧܥɺුಈখ਺఺ • ήετ: hikalium͞Μ
 ʮ30೔ͰͰ͖ΔʂOSࣗ࡞ೖ໳ʯɺηΩϡϦςΟΩϟϯϓͷCίϯύΠϥ࡞੒ίʔε • ςʔϚ: ౦େCPU࣮ݧ
 FPGA্ʹCPUճ࿏Λ࡞੒ͯ͠ఏڙ͞ΕͨϨΠτϨʔγϯάϓϩάϥϜΛ૸ΒͤΔ
 
 ਖ਼௚ɺ7~8ׂ࿩ͷ಺༰͕Α͘෼͔Βͳ͍
  3. ΤϛϡϨʔλͷߏ଄ମ // 1MB 0x00000 - 0xfffff pub const MEMORY_SIZE: u32

    = 1024 * 1024; enum Register { EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 } pub struct Emulator { pub memory: Vec<u8>, eip: u32, register: [u32; 8], eflags: u32 } ΠϯετϥΫγϣϯϙΠϯλ 32ϏοτϨδελ (8ݸ) ൺֱɺԋࢉɺ৚݅δϟϯϓ ϝϞϦ
  4. ΤϛϡϨʔλͷجຊಈ࡞ ϓϩάϥϜ (όΠφϦ) ϓϩάϥϜ ϝϞϦ (1MB) ϓϩάϥϜΛϝϞϦʹಡΈࠐΉ Φϖίʔυʹै͍ ॱ൪ʹ࣮ߦ͍ͯ͘͠ ΠϯετϥΫγϣϯ

    ϙΠϯλ (ϓϩάϥϜΧ΢ϯλ) ελοΫ ϓϩάϥϜ͕࢖༻͢ΔϝϞϦ ϓϩάϥϜͷ໭Γ৔ॴ ؔ਺ͷҾ਺ ϩʔΧϧม਺ 0xfffff 0x00000 Ϩδελ flags eip
  5. όΠτྻͷಡΈࠐΈ B801000000 B8 01000000 mov eax,0x1 όΠτྻ B8 1όΠτಡΉ (໋ྩ)

    32ϏοτϨδελEAXʹ஋Λίϐʔ mov eax,32Ϗοτଈ஋ 01000000 4όΠτಡΉ (஋1) EAXϨδελʹ1Λίϐʔ register[EAX] = 1 ϦτϧΤϯσΟΞϯ 00000001 eip += 5 ΠϯετϥΫγϣϯϙΠϯλΛਐΊΔ
  6. push, pop • ελοΫʹ஋Λpushɺpop͢Δ ϓϩάϥϜ ϝϞϦۭؒ ελοΫ 0xfffff 0x00000 ஋

    ஋ ஋ mov ebp, esp push esp mov ebx, 0x71234564 push ebx pop eax
  7. call, ret call sub ret sub: mov eax, 0x43252 ret

    ߦͬͯɺ஋ΛೖΕͯɺ΋ͲΔ ؔ਺ͬΆ͍
  8. ؔ਺ add(v1, v2) push 23 push 12 call add ret

    add: push ebp mov ebp, esp mov eax, [ebp+8] add eax, [ebp+12] mov esp, ebp pop ebp ret Ҿ਺2 Ҿ਺1 Ҿ਺1 Ҿ਺2 ελοΫ (Ҿ਺2) 23 (Ҿ਺1)12 ebp ݺͼग़͠ݩͷ࣍ͷ໋ྩ લͷebp [ebp+8] [ebp+12] [ebp+4]
  9. jmp, cmp, je • ൺֱɾforจ૬౰ɾ৚݅෼ذ • eflagsͷ࣮૷͕Ұ෦ඞཁ mov eax, 0

    mov ebx, 0 loop: cmp eax, 10 je exit add eax, 1 add ebx, 5 jmp loop exit: ret
  10. ϑΟϘφον਺ྻ (Cݴޠ) int f(int); int main() { int n =

    30; int res = 0; res = f(n); return res; } int f(int n) { if (n == 0 || n == 1) return n; else return (f(n-1) + f(n-2)); } $ gcc -m32 -Wl,--entry=main,--oformat=binary -nostdlib \ -fno-asynchronous-unwind-tables -o fibo fibo.c ਺ྻͷ30൪໨
  11. ϑΟϘφον਺ྻ 00000000 8D4C2404 lea ecx,[esp+0x4] 00000004 83E4F0 and esp,byte -0x10

    00000007 FF71FC push dword [ecx-0x4] 0000000A 55 push ebp 0000000B 89E5 mov ebp,esp 0000000D 51 push ecx 0000000E 83EC14 sub esp,byte +0x14 00000011 C745F41E000000 mov dword [ebp-0xc],0x1e 00000018 C745F000000000 mov dword [ebp-0x10],0x0 0000001F 83EC0C sub esp,byte +0xc 00000022 FF75F4 push dword [ebp-0xc] 00000025 E811000000 call dword 0x3b 0000002A 83C410 add esp,byte +0x10 0000002D 8945F0 mov [ebp-0x10],eax 00000030 8B45F0 mov eax,[ebp-0x10] 00000033 8B4DFC mov ecx,[ebp-0x4] 00000036 C9 leave 00000037 8D61FC lea esp,[ecx-0x4] 0000003A C3 ret 0000003B 55 push ebp 0000003C 89E5 mov ebp,esp 0000003E 53 push ebx 0000003F 83EC04 sub esp,byte +0x4 00000042 837D0800 cmp dword [ebp+0x8],byte +0x0 00000046 7406 jz 0x4e 00000048 837D0801 cmp dword [ebp+0x8],byte +0x1 0000004C 7505 jnz 0x53 0000004E 8B4508 mov eax,[ebp+0x8] 00000051 EB28 jmp short 0x7b 00000053 8B4508 mov eax,[ebp+0x8] 00000056 83E801 sub eax,byte +0x1 00000059 83EC0C sub esp,byte +0xc 0000005C 50 push eax 0000005D E8D9FFFFFF call dword 0x3b 00000062 83C410 add esp,byte +0x10 00000065 89C3 mov ebx,eax 00000067 8B4508 mov eax,[ebp+0x8] 0000006A 83E802 sub eax,byte +0x2 0000006D 83EC0C sub esp,byte +0xc 00000070 50 push eax 00000071 E8C5FFFFFF call dword 0x3b 00000076 83C410 add esp,byte +0x10 00000079 01D8 add eax,ebx 0000007B 8B5DFC mov ebx,[ebp-0x4] 0000007E C9 leave 0000007F C3 ret ਺ྻͷ30൪໨: 832040 ͜ͷΑ͏ͳίʔυ͕௨Δ·Ͱ ࣮૷Λଓ͚Δ IA-32 ΠϯςϧΞʔΩςΫνϟ ιϑτ΢ΣΞɾσϕϩούʔζɾϚχϡΞϧ ্רɾதרAɾதרBɾԼר
  12. ܭࢉͰ͖ͨ! --- START --- --- EXIT --- EAX = 0x000CB228

    832040 ECX = 0x00100000 1048576 EDX = 0x00000000 0 EBX = 0x00000000 0 ESP = 0x00100000 1048576 EBP = 0x00000000 0 ESI = 0x00000000 0 EDI = 0x00000000 0 ਺ྻͷ30൪໨: 832040 Ͱ΋ܭࢉʹ10ඵ͔͔Δ!