ãã®ã¢ã«ãŽãªãºã ã¯ã¯ã©ãã¯ããã®ãéåžžã«é£ããããããŸã§ã®ãšããããã®ããŒã¿ã解åããæ¹æ³ãåŠãã 人ã¯ããŸããã§ããã
åŒã³åºãã¯åãå ¥ããããŸããã 圌ã®èšäºã¯ã圌ãã¢ã«ãŽãªãºã ãã©ã®ããã«åŠçããããšãããã説æããŠããŸãã èªåã§ãããã©ã®ããã«è¡ã£ãããæžãçããæåŸã«ãMM3.CCãã¡ã€ã«ãå±éããã ãã§ãªããããã¯ã§ãããªãŒãã³ãœãŒã¹ãŠãŒãã£ãªãã£ãžã®ãªã³ã¯ãæäŸããŸãã
ãã¹ããã«ãŒ
MM3.EXEãèŠããšãããã¯å§çž®ãããŠããªããªãŒããŒã¬ã€ã®ããå§çž®ãããDOSå®è¡å¯èœãã¡ã€ã«ã§ããããã®å é ã¯FBOVã§ãã DOSã³ã³ãã¬ããµãŒã«ã€ããŠã¯äœãç¥ããŸããã§ããããJeff LudwigããUniversal Program Crackerãv1.11ãšåŒã°ãããã®ã䜿çšããŠããããšãã¹ãã€ããŸããã ããŒãžã§ã³1.10ïŒ1997幎6æ25æ¥ãªãªãŒã¹ïŒãèŠã€ããŠãexeã解åããŸããã ãããŠããªãŒããŒã¬ã€ããŒã¿ãæ£ããåŠçããããšããã§ããŸããã ããã§ããç§ã¯ããã«ãŒã®ååãç¥ãããã£ãã 圌ãã¯ç§ã«Detect It Easyããã°ã©ã ã䜿çšããå¿ èŠããããšèšã£ãããããŠå®éã«-ããã¯çºè¡ããïŒ
EXECUTRIX-COMPRESSOR(-)[by Knowledge Dynamics Corp] Borland TLINK(2.0)[-]
æŽå²ã®æ奜è ã«ã¯ããã®ãœãããŠã§ã¢ã«é¢ããå€ããã£ã¹ã«ãã·ã§ã³ã¹ã¬ããããå§ãããŸã-1991幎ãš1995幎ããïŒ
https://groups.google.com/forum/#!topic/comp.os.msdos.programmer/QsjHLY6Kb4s
https://groups.google.com/forum/#!topic/comp.compression/IAj2-VHbtl4
IDA DOSããŒããŒ
exeã解åããããšã¯è¯ãããšã§ãããé©åã«å解ããããšã¯ããã«åªããŠããŸãã æ®å¿µãªãããIDAã¯ããã«ã€ãŸãããã 圌ã¯ãªãŒããŒã¬ã€ãæ£ããæ€åºããŸããããããŒãã§ããŸããã§ããã ã³ãŒãã確èªããåŸãã³ãŒãã®ã»ã¯ã·ã§ã³ãæããã«ã¹ããããããŠããããããªãŒããŒã¬ã€ãªãã§åæãããšé çã«ãªãããšãããããŸããïŒè§£åæé ã¯exeãã¡ã€ã«ã«ä¿åãããŠããŸããïŒã Googleã§FBOVãæ€çŽ¢ããŠãããšãã«ãIDA DOSããŒããŒã®ãœãŒã¹ã³ãŒãã«åºäŒããIDAãåé¡ãªããã®ãªãŒããŒã¬ã€ãããŒãã§ããããšã確èªããŸããã IDA DOSããŒããŒã®ãããã°ããŒãžã§ã³ãåã³ã³ãã€ã«ãããã®äœæ¥ãVisual Studioã§è¿œè·¡ããŠããªãŒããŒã¬ã€ãèªã¿èŸŒãŸããªãçç±ãç解ããŸããã ãããè¡ãã«ã¯ãFBOVæ§é ã®ããã€ãã®å éšãã©ã¡ãŒã¿ãŒãèšè¿°ããå¿ èŠããããŸããã ã¿ã€ãã«ã®èª¬æã¯æ¬¡ã®ãšããã§ãã
#define FB_MAGIC 0x4246 #define OV_MAGIC 0x564F struct fbov_t { ushort fb; // = FB_MAGIC ushort ov; // = OV_MAGIC uint32 ovrsize; uint32 exeinfo; int32 segnum; };
exeinfo-ãªãŒããŒã¬ã€ã«ä¿åãããŠããåã»ã°ã¡ã³ããèšè¿°ããæ§é äœã®é åã®ãªãã»ããïŒçµ¶å¯ŸãMZããããŒã®å é ããïŒã segnum-ã»ã°ã¡ã³ãã®æ°ã ãããã¯ãã®ãããªæ§é ã«ãã£ãŠèšè¿°ãããŸãïŒ
struct seginfo_t { ushort seg; ushort maxoff; ushort flags; ushort minoff; };
ããã¯çè«äžãã¹ãŠã§ãããIDA DOSããŒããŒã§ã¯ãããã¯ãã¹ãŠLoadCppOverlaysïŒïŒé¢æ°ã§å®è£ ãããŸãã ããããçè«ã¯ãã®exeã§åäœããªããªããŸã-çå®ã¯ãã»ãã®æ°ãã€ããééã£ãŠããã ãã§ãã ãããã°äžã«ãexeinfoãåè¿°ã®ã»ã°ã¡ã³ãã®é åã®çŽåŸã®äœçœ®ãæããŠããããšã«æ°ä»ããŸããã LoadCppOverlaysïŒïŒã«1è¡è¿œå ããŸããïŒ
fbov.exeinfo -= fbov.segnum*sizeof(seginfo_t);
ãããŠããã¯åããã FBOVã«é¢ããããã¥ã¡ã³ããèŠã€ãããªãã£ãããããããã®ãªãŒããŒã¬ã€ã®å®è£ ãããã€ããããã©ããã¯ããããŸããã IDA DOSããŒããŒã«ã¯æ£ããããŒãžã§ã³ã§ã®äœæ¥ãå®è£ ãããŠãããšç¢ºä¿¡ããŠããŸãããªããªãããããæžãã人ãå®äŸã§ããã確èªããããã§ãã ãã¶ããããã¯ç¥ã£ãŠããMM3éçºè ã®ç¹å¥ãªæ©èœã ã£ããããããŸããã
ã¢ã³ããã«ãŒãæ¢ããŠããŸã
æ€çŽ¢ã«ã¯ãDOSBoxãããã¬ãŒãšint 21hïŒDOS APIãæäœããããã®æšæºå²ã蟌ã¿ïŒã«ãããã¬ãŒã¯ãã€ã³ãã®ã»ããã䜿çšããŸããã ç§ã¯ã3DhïŒãã¡ã€ã«ãéãïŒã3FhïŒãã¡ã€ã«ãèªãïŒã42hïŒãã¡ã€ã«ãæ€çŽ¢ããïŒã®æ©èœã«ç¹ã«èå³ããããŸããã ãããŠããã«ãæ¢ããŠãããã®ãèŠã€ãããŸããã
ã¢ã«ãŽãªãºã åæ
çŸåšãããã«ãŒ/ã¢ã³ããã«ãŒã®ã»ãŒãã¹ãŠã®ãããã³ã°ã¯Hex-Rays Decompilerãä»ããŠè¡ãããŸãããããã¯ããã»ã©é£ãããããŸããã ãã ããã¢ã»ã³ãã©ãŒ16ãããx86ã§ã¯æ©èœãããåäœããå¯èœæ§ã¯äœãã§ãã æåã®éçã¢ã³ããã«ãŒãäœæãã2005幎ã«æ»ã£ããšæãããŸãã IDA 4.9ã®æ代ã§ãããã2006幎3æã«ç»å ŽãããããŒãã£ãŒãã衚瀺ããããã®ã€ã³ã¿ã©ã¯ãã£ãã¢ãŒããããããŸããã§ããã ã¢ã³ããã«ãŒã®ã°ã©ãã£ã«ã«ãªè¡šçŸãæäŸããŸãã
玫è²ã®ãããã¯-ã¢ã«ãŽãªãºã ã®åæåãè¶è²-ã¡ã€ã³ã®ã¢ã³ããã¯ãµã€ã¯ã«ãçœè²-CCãã¡ã€ã«ã®ã¡ã¢ãªãšæ§é ãæäœããŸãã éåžžãã¢ã»ã³ãã©ããã®ã¢ã«ãŽãªãºã ã®æœåºã«ã¯ããã€ãã®æé ãå¿ èŠã§ãã
1.ããŒã¿åéã è€éãã¯ãã¢ã«ãŽãªãºã ã®è€éãã«äŸåããŸãã èšç®ã§äœ¿çšã§ããå ¥åããã³åºåãããã¡ãŒãäžæãããã¡ãŒãå€æ°ïŒããŒã«ã«ããã³ã°ããŒãã«ïŒãããã³å®æ°ã«é¢ããæ å ±ãåéããå¿ èŠããããŸãã äœæ¥ãç°¡çŽ åããã«ã¯ãå€æ°ãã¬ãžã¹ã¿ã®ååïŒ_axã_bxã_cxãªã©ïŒã«äŒŒãŠããCPUã¬ãžã¹ã¿ã«å²ãåœãŠãå¿ èŠããããŸãã å€æ°ã®åã¯ãã¬ãžã¹ã¿ã®ãµã€ãºã«å¯Ÿå¿ããŠããå¿ èŠããããŸãããã®äŸã§ã¯ãuint16_tã§ãã å Žåã«ãã£ãŠã¯ãã¬ãžã¹ã¿ã®8ãããéšåãžã®ã¢ã¯ã»ã¹ãç°¡çŽ åããããã«ãã¬ãžã¹ã¿ããŠããªã³ãšããŠè¡šãæ¹ãé©åã§ãã ããŒã«ã«å€æ°ãšã°ããŒãã«å€æ°ã®æäœã¯ãç¹ã«æåã¯ããªãè€éã§ããããã¯ãããã1.2.4ãã€ããå æããå€æ°åã§ãããããããšãé åã§ããããåžžã«æ確ã§ã¯ãªãããã§ãã äºãã«è¿ãã«ããã¡ã¢ãªã¢ãã¬ã¹ãžã®ã¢ã¯ã»ã¹ãéåžžã«å€ãå Žåãããã¯é åã§ãããšèŠãªãããšãã§ããåŸã§ãé åã®ããã«ã¢ã¯ã»ã¹ãããå Žåãããããå¥ã ã®å€æ°ã«åããããšãã§ããŸãã ããã¯ãããŒã«ã«å€æ°ãæäœããå Žåã«ç¹ã«äŸ¿å©ã§ãããããã£ãŠãesp / ebpãžã®ãã¹ãŠã®ã¢ã¯ã»ã¹ã¯ãé åãä»ããŠåŠçããå¿ èŠããããŸãïŒç°¡åã«ããããã_stackãšåŒã³ãŸãããïŒã ãã®ãã§ãŒãºã§ã¯ãæ¢ç¥ã®ããŒã¿ããã¹ãŠåæåããããšãéåžžã«éèŠã§ãã
2.ãµã€ã¯ã«ã®æ€çŽ¢ã¯ãç§ã«ãšã£ãŠæãèå³æ·±ããã®ã§ãã IDAã®ã€ã³ã¿ã©ã¯ãã£ããªã°ã©ãã£ã«ã«ãã¬ãŒã³ããŒã·ã§ã³ã¯ãããã«æé©ãªããŒã«ã®1ã€ã§ãã æãåçŽãªå éšãµã€ã¯ã«ããå§ããŠãäžã«è¡ãã®ã䟿å©ã§ãã åãµã€ã¯ã«ã¯ãç°ãªãè²ã§ãã€ã³ãããŠã°ã«ãŒãåã§ããŸãã ã«ãŒããã°ã«ãŒãåãããšãã°ã©ãã£ã«ã«ãªè¡šç€ºãç°¡åã«ãªããå åŽã®ã«ãŒããé衚瀺ã«ãããšã次ã®ã¬ãã«ãžã®ã«ãŒããèŠã€ããããšãã§ããŸãã
3.ã³ãŒãã®æžãæãã¯æãéå±ãªéšåã§ãã ãããã¯ããšã«ãåãªãã³ãŒããŸãã¯ãªãã³ãŒãã°ã«ãŒããé«ã¬ãã«èšèªã®åŒã«æžãæããŸãã ãã¹ãŠã®ãµã€ã¯ã«ãæ£ããæ€åºãããå Žåããããè¡ãã®ã¯ããã»ã©é£ãããããŸããããéå±ãªäœæ¥ã®ããã«ããã®éšåã¯ãšã©ãŒãèµ·ãããããã§ãã æ®ãã®ããžãã¯ã¯ãé«æ°Žæºèšèªã«ç°¡åã«ç¿»èš³ã§ããæ¡ä»¶åŒã§ãã åŠçæžã¿ã®ãããã¯ãæ··åããªãããã«ãç°ãªãè²ã§ããŒã¯ãããšäŸ¿å©ã§ãã
4.æ€èšŒã ã»ãšãã©ã®å ŽåãåããŠä»äºãããããšã¯ãããŸããã æåã®3ã€ã®æ®µéã§è¡ãããééãã¯äžè¬çã§ãããèŠã€ããã®ã¯å°é£ã§ãã éåžžãããããä¿®æ£ããã«ã¯ãå ã®ã³ãŒããšããŒãžã§ã³ã®2ã€ã®ãããã¬ãŒãåæã«èµ·åããå¿ èŠããããŸãã
5.è£ é£Ÿã³ãŒãã ãã¹ãŠãæ©èœããããã³ãŒãã調ã¹ãŠã以åã¯äžæã«èå¥ãããªãã£ããã¹ãŠã®å€æ°ãé åãããã³å®æ°ãåŠçãããšããã§ãããã ãŸããå€æ°ã«éåžžã®ååãä»ããŠãã¢ã»ã³ãã©ãŒãæš¡å£ãããªãã·ã§ã³ã®æ§æèŠçŽ ãåãé€ãããšãæå¹ã§ãã çæ³çã«ã¯ããã®åŸãã¹ã¿ãã¯ãæš¡å£ããx86ã¬ãžã¹ã¿ãŸãã¯é åã«ã¡ãªãã§åä»ããããå€æ°ã¯ãªãã¯ãã§ãã ãã¹ãŠãéåžžã®é«ã¬ãã«ã³ãŒãã®ããã«èŠããã¯ãã§ãã
Might and Magic IIIã®å Žåããã¹ãŠã®æ®µéãçµãŠãæåŸã«äœæ¥çšã®ã¢ã³ããã«ãŒãåãåããŸããã ã»ã¯ã·ã§ã³4ã®ãšã©ãŒãåé¿ããããã«ãå ã®ã³ãŒãã®ãããã¬ãŒã§äœæ¥ããæžãæããããåã·ã³ãã«ãããã¯ããã§ãã¯ããŠãåäžã®ã¢ã»ã³ãã©ãŒã³ãŒããçæããŸããã MM3.CCã®ãã¹ãŠã®å§çž®ã¹ããªãŒã ã調ã¹ãŠã¿ããšãã¢ã«ãŽãªãºã ã®ãã©ã³ãã®1ã€ãé¢äžããŠããªãããšãããã£ããããä»ã®ãšãã空ã®ãŸãŸã«ããŸããã ã°ã©ãã®èµ€ããããã¯ã¯ãã²ãŒã ãã¡ã€ã«ã§å®è¡ãããŠããªãéšåã瀺ããŠããŸãã
ããããã¢ã«ãŽãªãºã ã®ååãã°ãŒã°ã«ã§å§ããŸããã ã³ãŒãã«ãã16é²å®æ°ãšãdecompressããšããåèªãæ€çŽ¢ããŸããã
ã0x13Aã解å
ã0x4E6ã解å
ã0x274ã解å
ã0x139ã解å
ã0xFC4ã解å<-æå
Amigaã®å€ããã©ãŒãããã®ã¢ã³ããã«ãŒã®ãœãŒã¹ã³ãŒããèŠã€ããŸããã ãã®å®æ°ã«å ããŠãMM3ã«ã¯ããŒãã«å®æ°ãæ瀺ãããŠããŸããã MM3ã¯LZHUFã¢ã«ãŽãªãºã ã䜿çšããããšãå€æããŸããã ãããåŠã¶ãšãããã«åãåã£ãã³ãŒããã³ãŒãã³ã°ãã ãã®ãœãŒã¹ããã¢ã«ãŽãªãºã ã®æ¬ èœéšåïŒèµ€ããããã¯ïŒãã³ããŒããŸããã MM3ããŒãžã§ã³ã¯ãããã€ãã®äŸå€ãé€ããŠå ã®LZHUFå®è£ ãšåãã§ã-0x20å€ã䜿çšããŠèŸæžãåæåãã代ããã«ãåŒæ°ããååŸããå€ã䜿çšããŸãã ãã¡ã€ã«MM3.CCå ã®ãã¹ãŠã®å§çž®ã¹ããªãŒã ã®8ãããå€ã¯ç°ãªããŸãã ãããã®å Žåããããã¯ããŒã¿ã®æãäžè¬çãªãã€ãã ãšæããŸããã
MM3.CCããã«ãŒ/ã¢ã³ããã«ãŒ
ç§ã¯ãä»ã®èª°ãã䜿çšã§ããéåžžã®ãŠãŒãã£ãªãã£ã䜿çšããŠãã¿ã€ã¿ããã¯äœæ¥ãçµäºããããšã«ããŸããã CCãã¡ã€ã«ã®åœ¢åŒã¯Xeen Wikiã§èª¬æãããŠããŸããããã®èª¬æã¯Might and Magic IVããã³Vã®CCãã¡ã€ã«ã§ã®ã¿æ©èœããŸããMM3.CCã¯åæ§ã®ãã¡ã€ã«æ§é ãæã¡ãŸããããã¡ã€ã«åãšå§çž®ãããã·ã¥ããŸãã ãã¡ã€ã«ããããŒãšã³ã³ãã³ãããŒãã«ã¯ãXeen Wikiã§èª¬æãããŠãããã®ãšãŸã£ããåãã§ãã
struct FileEntry; struct FileHeader { uint16_t NumberOfFileEntries FileEntry FileEntries[NumberOfFileEntries]; }; struct FileEntry { uint16_t hash; uint16_t offsetLo; uint8_t offsetHi; uint16_t compressedSize; // includes 4 bytes header uint8_t padding; };
FileEntriesé åã¯ã次ã®ã¢ã«ãŽãªãºã ã§æå·åãããŸãïŒXeen Wikiã§æå®ãããŠãããã®ãšåãïŒã
void encryptHeader(uint8_t* buf, size_t size) { uint8_t key = 0xAC; for (size_t i = 0; i < size; i++) { buf[i] = _rotr8(buf[i] - key, 2); key += 0x67; } } void decryptHeader(uint8_t* buf, size_t size) { uint8_t key = 0xAC; for (size_t i = 0; i < size; i++) { buf[i] = _rotl8(buf[i], 2) + key; key += 0x67; } }
SSã³ã³ããå ã®ãã¡ã€ã«ã¯ã16ãããããã·ã¥ïŒFileEntry.hashïŒã«ãã£ãŠèå¥ãããŸãã
uint16_t hashFileName(const char* fileName) { uint16_t hash = 0; while (0 != *fileName) { uint8_t c = ((*fileName & 0x7F) < 0x60) ? *fileName : *fileName - 0x20; hash = _rotl16(hash, 9); // xchg bl, bh | rol bx, 1 hash += c; fileName++; } return hash; }
æåã®2ã€ã®ãã¡ã€ã«ã¯ç¹å¥ã§ãã ãããã¯å§çž®ãããŠããªãããã¹ãã§ããããã®ãµã€ãºã¯exeãã¡ã€ã«ã«çŽæ¥æžã蟌ãŸãããããå€æŽããªãæ¹ãè¯ãã§ãããã æ®ãã¯ãã¹ãŠå§çž®ãããããŒã¿ãããã¯ã§ãåãããã¯ã®å é ã«å°ããªèšè¿°åããããŸãã
{ uint16_t decompressionInitializer; uint16_t decompressedSize; }
decompressionInitializerã¯åžžã«äžäœ8ããããšäžäœ8ãããã«8ãããå€ãæ ŒçŽãããããuint8_tã«ããããšãã§ããŸãã ãªããã®ããã«ä¿åãããã®ãããããŸããã decompressedSizeã¯ããã°ãšã³ãã£ã¢ã³å€ã«æ ŒçŽãããŸããããããå¥åŠã§ãã ãã1ã€ã®å¥åŠãªç¹ã¯ããŠãŒãã£ãªãã£ã䜿çšããŠåå§çž®ããåŸãMM3.CCãã¡ã€ã«ã33 Kbæžå°ããããšã§ãã ãŸããMM3.EXEããã³ã³ãã€ã«ããããã¡ã€ã«åã®ãªã¹ããçšæããŸãããããã«ããã解åæã«æ£ãããã¡ã€ã«åãååŸãããŸãïŒãªã¹ããäžå®å šã§ã-556åã®ãã¡ã€ã«åã®ãã¡15åãã¹ãããããŸããïŒã ããã§ã»ãŒå®äºã§ããMM3.CCãã¡ã€ã«ããã«ãŒ/ã¢ã³ããã«ãŒãååšããgithubãªããžããªãžã®ãªã³ã¯ãæäŸããŠããŸã
github.com/rwfpl/rewolf-mm3-dumper
å§çž®ã¯ããããªå€æŽãå ããŠæšæºã®LHUFããååŸããã解åã¯3æ¥éã®ãªããŒã¹ãšã³ãžãã¢ãªã³ã°ã®çµæã§ãã ã¹ã¯ã€ãŒã¶ãŒãšã¢ã³ããŒããŒã¯ãããã¡ãŒããã§ãã¯ããªããããæ·±å»ãªç®çã§äœ¿çšããããšã¯ãå§ãããŸããã ãããã®äœ¿çšã¯ç°¡åã§ãïŒ
x:\mm3>mm3_cc_dumper.exe Might and Magic III CC file packer/unpacker v1.0 Copyrigh (c) 2015 ReWolf http://blog.rewolf.pl Usage: Unpack: mm3_cc_dumper.exe dump input_file.cc Pack: mm3_cc_dumper.exe pack input_directory output_file.cc