|
楼主 |
发表于 2025-4-19 18:45:01
|
显示全部楼层
本帖最后由 wyz_2015 于 2025-4-19 19:34 编辑
关于AW板rom的解密是有进展了。
思路不是照猫画虎,借别人代码做自己的功能。而是当“小偷”,在模拟器做好解密后,插入一段“抄作业”的代码,把解密好的rom内容从内存拷贝到外存。
“迫害”对象选的flycast,其相关代码多从MAME修改而来。MAME里的代码里太多“FUNC”等宏了,不知道怎么处理好,故转向使用“二手”的flycast。
flycast具体的版本是:2025-03-08 06:19:55的master分支的版本,SHA1为48bce2582086883c710eeb637f20fe593a3b708a。
代码改动了3处。额外添加的代码周围有类似这样的注释:
- /* modify */
- 额外的代码……
- /* */
复制代码
还有
也是要的,在这就省略不提了。
core/hw/naomi/naomi_cart.h - class Cartridge
- {
- public:
- Cartridge(u32 size);
- virtual ~Cartridge();
- virtual void Init(LoadProgress *progress = nullptr, std::vector<u8> *digest = nullptr) {
- if (digest != nullptr)
- digest->clear();
- }
- virtual u32 ReadMem(u32 address, u32 size) = 0;
- virtual void WriteMem(u32 address, u32 data, u32 size) = 0;
- virtual bool Read(u32 offset, u32 size, void* dst);
- virtual bool Write(u32 offset, u32 size, u32 data);
- virtual void* GetPtr(u32 offset, u32& size);
- virtual void* GetDmaPtr(u32 &size) = 0;
- virtual void AdvancePtr(u32 size) = 0;
- virtual void Serialize(Serializer& ser) const {}
- virtual void Deserialize(Deserializer& deser) {}
- virtual void SetKey(u32 key) { }
- virtual void SetKeyData(u8 *key_data) { }
- virtual bool GetBootId(RomBootID *bootId) = 0;
- const Game *game = nullptr;
- /* modify */
- u8* myRomPtr;
- u32 myRomSize;
- /* */
- protected:
- u8* RomPtr;
- u32 RomSize;
- };
复制代码
core/hw/naomi/naomi_cart.cpp - void naomi_cart_LoadRom(const std::string& path, const std::string& fileName, LoadProgress *progress)
- {
- // 省略原代码。我是在这个函数的最后追加东西的
- #endif
- }
- else
- {
- NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", settings.content.gameId.c_str());
- }
- /* modify */
- FILE *binFile = fopen("/tmp/ms6原始加密.bin", "wb"), *binFile2 = fopen("/tmp/ms6用decrypt16函数解密.bin", "wb"), *binFile3 = fopen("/tmp/ms6用decrypt16_2函数解密.bin", "wb"); // 为了自己方便,我是直接写死路径的。若有需要,应根据自身电脑系统作修改。
- if (!(binFile && binFile2 && binFile3)) {
- exit(1);
- }
- fwrite(CurrentCartridge->myRomPtr, CurrentCartridge->myRomSize, 1, binFile);
- fclose(binFile);
- AWCartridge* cc = (AWCartridge*)CurrentCartridge;
- // printf("\n\n%08x\n\n", cc->myRomSize);
- for (uint32_t address = 0; address < CurrentCartridge->myRomSize; address += 1) {
- // printf("%08x\t", address);
- uint16_t d = cc->decrypt16(address);
- fwrite(&d, sizeof(uint16_t), 1, binFile2);
- }
- fclose(binFile2);
- for (uint32_t address = 0; address < CurrentCartridge->myRomSize; address += 1) {
- // printf("%08x\t", address);
- uint16_t d = cc->decrypt16_2(address);
- fwrite(&d, sizeof(uint16_t), 1, binFile3);
- }
- fclose(binFile3);
- /* */
- }
复制代码- Cartridge::Cartridge(u32 size)
- {
- RomPtr = (u8 *)malloc(size);
- myRomPtr = RomPtr; // modify
- if (RomPtr == nullptr)
- throw NaomiCartException("Memory allocation failed");
- RomSize = size;
- myRomSize = RomSize; // modify
- if (size != 0)
- memset(RomPtr, 0xFF, RomSize);
- }
复制代码
core/hw/naomi/awcartridge.h - class AWCartridge: public Cartridge
- {
- public:
- AWCartridge(u32 size) : Cartridge(size) {}
- void Init(LoadProgress *progress = nullptr, std::vector<u8> *digest = nullptr) override;
- u32 ReadMem(u32 address, u32 size) override;
- void WriteMem(u32 address, u32 data, u32 size) override;
- void *GetDmaPtr(u32 &size) override;
- void AdvancePtr(u32 size) override;
- bool GetBootId(RomBootID *bootId) override;
- void SetKey(u32 key) override;
- void Serialize(Serializer& ser) const override;
- void Deserialize(Deserializer& deser) override;
- /* modify */
- u16 decrypt16_2(u32 address) { return decrypt(((u16 *)RomPtr)[address], address, rombd_key); }
- u16 decrypt16(u32 address) { return decrypt(((u16 *)RomPtr)[address % (RomSize / 2)], address, rombd_key); } // 这个方法是从下面private移动到上面来的,不然没法在类外调用。
- /* */
- private:
- void device_reset();
- enum { EPR, MPR_RECORD, MPR_FILE };
- u32 rombd_key;
- u32 mpr_offset, mpr_bank;
- u32 epr_offset, mpr_file_offset;
- u16 mpr_record_index, mpr_first_file_index;
- u16 decrypted_buf[16];
- u32 dma_offset, dma_limit;
- struct sbox_set {
- u8 S0[32];
- u8 S1[16];
- u8 S2[16];
- u8 S3[8];
- };
- static const u8 permutation_table[4][16];
- static const sbox_set sboxes_table[4];
- static const int xor_table[16];
- static u16 decrypt(u16 cipherText, u32 address, u8 key);
- // u16 decrypt16(u32 address) { return decrypt(((u16 *)RomPtr)[address % (RomSize / 2)], address, rombd_key); }
- void recalc_dma_offset(int mode);
- };
复制代码
我只拿mslug6做实验。修改代码后再编译出模拟器,载入mslug6 aw版的rom,程序会报“段错误”退出。而相应目录下的确出现了3个bin文件。
我不明白decrypt16函数中为什么要取一个address % (RomSize / 2)。我复制了它,取名decrypt16_2,改成直接取address。
执行原版函数,程序能正常跑完,但是所得rom文件的内容,重复了大概3遍。执行修改版的函数,程序就报“段错误”退出:我是在linux下操作的,“段错误”是操作了未分配的内存空间会出现的报错。
以上,求指教。 |
|