Soron

DCPU DRM cracking: challenge accepted

May 12th, 2012
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.37 KB | None | 0 0
  1. ; written by Eidako
  2. ; Cracked by Soron (with implicit permission)
  3.  
  4. ; This was decrypted from a challenge that was posted to Reddit
  5. ; Orginal Reddit thread: http://www.reddit.com/r/dcpu16/comments/tivjz/drm_decompiler_resistant_code_good_luck/
  6. ; Challenge in machine code form: http://pastebin.com/GKbeL9sq
  7. ; First disassembled pass: http://pastebin.com/q9GfMVDb
  8.  
  9. ; I've left the original decryption code in place, so you can see how it works ;).
  10.  
  11.  
  12. ; two no-ops to get words to line up properly
  13. ; original was "SET PC, start_decrypting"
  14. SET A, A
  15. SET A, A
  16.  
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18. ; START DECRYPTED BLOCK 2 ;
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20.  
  21. ; this decrypted block writes the string to the screen, then overwrites memory
  22. ; note: the string was also decrypted in this block
  23.  
  24.  
  25. ; dude, you have no HWI. You're also not checking which port the monitor is attached to.
  26. ; ergo, this will break on any emulator that doesn't start with the screen memory
  27. ; mapped to 0x8000
  28. :start_writing
  29. SET I, 0x80a0
  30. SET J, the_string
  31.  
  32. :write_loop
  33. BOR [J], 0xf000
  34. STI [I], [J]
  35. IFN [J], 0
  36. SET PC, write_loop
  37. SET PC, garble_decrypted_memory
  38.  
  39. DAT 0x0001 ; I have no idea why, but word count got thrown off by 1 somewhere. Meh. Fixing that with a no op.
  40.  
  41. :the_string ; started at memory position 13 (or 0xD)
  42. DAT 0x0054, 0x0068, 0x0061, 0x0074, 0x0027, 0x0073, 0x0020, 0x0073, 0x0074, 0x0072, 0x0061, 0x006e, 0x0067, 0x0065, 0x002c, 0x0020, 0x0074, 0x0068, 0x0069, 0x0073, 0x0020, 0x0073, 0x0074, 0x0072, 0x0069, 0x006e, 0x0067, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0064, 0x0069, 0x0064, 0x006e, 0x0027, 0x0074, 0x0020, 0x0073, 0x0068, 0x006f, 0x0077, 0x0020, 0x0075, 0x0070, 0x0020, 0x0069, 0x006e, 0x0020, 0x0074, 0x0068, 0x0065, 0x0020, 0x0073, 0x006f, 0x0075, 0x0072, 0x0063, 0x0065, 0x002e, 0x002e, 0x002e, 0x0000, 0x0054, 0x0068, 0x0065, 0x0020, 0x0070, 0x0061, 0x0073, 0x0073, 0x0077, 0x006f, 0x0072, 0x0064, 0x0020, 0x0069, 0x0073, 0x0020, 0x0027, 0x0065, 0x006c, 0x0061, 0x006b, 0x0061, 0x006a, 0x006f, 0x006f, 0x0027, 0x002e, 0x0000
  43.  
  44. :garble_decrypted_memory
  45. SET J, 0x0075
  46. SET A, 0x8781
  47. XOR B, B
  48. XOR C, C
  49. XOR X, X
  50. XOR Y, Y
  51. XOR Z, Z
  52. XOR I, I
  53. XOR SP, SP
  54. XOR EX, EX
  55.  
  56. :garble_loop
  57. ; so, you do know that you're leaking some decrypted memory, by not wiping both decrypted blocks, right?
  58. ; might be better to set I to a suitable value, use "SET [I], A" as well,
  59. ; and set A to the machine code for "SUB PC, 1"
  60. STD [J], A
  61. MOD J, 0x8000
  62. SET PC, garble_loop
  63.  
  64. ; I have no friggin' idea what the next block is all about. Red herring?
  65.  
  66. DAT 0xf575, 0x4db7, 0x90c4, 0x286b, 0xde68, 0xf0ec, 0x004b, 0xeef5, 0xfb76, 0x1029, 0xc30a, 0x22c0, 0xfc71, 0x3328, 0x9bbf, 0x7952, 0x34c5, 0x121d, 0x7bc7, 0xb14d, 0xe665, 0xaa1f, 0xf017, 0xfb87, 0xa81a, 0xeb82, 0xd684, 0x8ad5, 0x3eb6, 0x092c, 0x0fff, 0x98a5, 0xe1ad, 0xf63e, 0xc40e, 0xc371, 0x699e, 0xfd76, 0xa48d, 0xdeb7, 0x3e78, 0x4c6c
  67.  
  68. ;;;;;;;;;;;;;;;;;;;;;;;;;
  69. ; END DECRYPTED BLOCK 2 ;
  70. ;;;;;;;;;;;;;;;;;;;;;;;;;
  71.  
  72.  
  73.  
  74. :start_decrypting
  75. JSR first_decrypt_pass
  76. STI X, Y
  77. SET PC, I ; equivalent to "SET PC, second_decrypt_pass"
  78.  
  79.  
  80. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  81. ; START DECRYPTED BLOCK 1 ;
  82. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  83.  
  84. ; this decrypted block decrypts block 2
  85.  
  86.  
  87. DAT 0x8f93 ; I think this is just a garbage value intended to throw people off
  88.  
  89. :second_decrypt_pass
  90. SET A, [0x007d]
  91. ADD A, [0x0083]
  92. SET A, [A]
  93. SET B, [0x008e]
  94. SUB B, [0x0085]
  95. SET B, [B]
  96. SET C, [0x0091]
  97. ADD C, [0x00a0]
  98. SET C, [C]
  99. SET I, 2
  100.  
  101. :second_decrypt_loop ; this label could possibly be moved up one instruction, not sure if it was in the original or not
  102. SET J, 0x00a5
  103. SET PUSH, [I]
  104. ADD [I], B
  105. XOR [I], A
  106. SHL [I], C
  107. BOR [I], EX
  108. ADD A, POP
  109. ADD C, A
  110. MOD C, 0x0010
  111. SHL B, C
  112. BOR B, EX
  113. ADD I, 1
  114. IFL I, J
  115. SET PC, second_decrypt_loop
  116. SET PC, start_writing
  117.  
  118. ;this DAT looks like more garbage intended to throw people off, to me
  119. DAT 0x2d91, 0xe6b6, 0x5d0b, 0x4b57, 0x1ffa, 0x4721
  120.  
  121. ;;;;;;;;;;;;;;;;;;;;;;;;;
  122. ; END DECRYPTED BLOCK 1 ;
  123. ;;;;;;;;;;;;;;;;;;;;;;;;;
  124.  
  125. :first_decrypt_pass
  126. XOR I, I
  127. SUB I, 0xff36
  128. SET X, I
  129. SUB X, 0x0021
  130. SET J, [0x0097]
  131. ADD J, [0x009b]
  132.  
  133. :first_decrypt_loop
  134. XOR [I], J
  135. STD A, A
  136. IFG I, X
  137. SET PC, first_decrypt_loop
  138. DAT 0x6381, 0xbf26, 0x7f4c, 0x6099, 0x823f, 0x4e35, 0xfb87, 0x7f81, 0x0000
Add Comment
Please, Sign In to add comment