First working demonware emulator
This commit is contained in:
parent
1d0f79623f
commit
7c1c819a56
@ -17,7 +17,7 @@ Reverse engineering and analysis of Call of Duty: Black Ops 3. Very experimental
|
|||||||
- [x] RE Tool Detection Bypass (IDA Pro, HxD, ...)
|
- [x] RE Tool Detection Bypass (IDA Pro, HxD, ...)
|
||||||
- [x] Disable Hardware Breakpoint Detection
|
- [x] Disable Hardware Breakpoint Detection
|
||||||
- [x] Disable Integrity Checks
|
- [x] Disable Integrity Checks
|
||||||
- [ ] Demonware Emulation
|
- [x] Demonware Emulation
|
||||||
- [ ] Disable Anti-Debugging Mechanisms
|
- [ ] Disable Anti-Debugging Mechanisms
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
@ -481,6 +481,10 @@ namespace demonware
|
|||||||
utils::hook::copy_string(0x1430B93C8_g, "http://%s:%d/auth/");
|
utils::hook::copy_string(0x1430B93C8_g, "http://%s:%d/auth/");
|
||||||
|
|
||||||
utils::hook::set<uint32_t>(0x141EC4B50_g, 0xC3D08948); // Skip publisher file signature stuff
|
utils::hook::set<uint32_t>(0x141EC4B50_g, 0xC3D08948); // Skip publisher file signature stuff
|
||||||
|
|
||||||
|
utils::hook::set<uint32_t>(0x141EC4B40_g, 0xC301B0); // FFOTD is valid
|
||||||
|
utils::hook::set<uint32_t>(0x141EBDF30_g, 0xC301B0); // DDLs available
|
||||||
|
utils::hook::set<uint32_t>(0x141E968F0_g, 0xC301B0); // QOL finished
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
|
@ -72,6 +72,33 @@ namespace demonware
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bdFileQueryResult final : public bdTaskResult
|
||||||
|
{
|
||||||
|
std::uint64_t user_id;
|
||||||
|
std::string platform;
|
||||||
|
std::string filename;
|
||||||
|
std::uint32_t errorcode;
|
||||||
|
std::string filedata;
|
||||||
|
|
||||||
|
void serialize(byte_buffer* data) override
|
||||||
|
{
|
||||||
|
data->write_uint64(user_id);
|
||||||
|
data->write_string(platform);
|
||||||
|
data->write_string(filename);
|
||||||
|
data->write_uint32(errorcode);
|
||||||
|
data->write_blob(filedata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deserialize(byte_buffer* data) override
|
||||||
|
{
|
||||||
|
data->read_uint64(&user_id);
|
||||||
|
data->read_string(&platform);
|
||||||
|
data->read_string(&filename);
|
||||||
|
data->read_uint32(&errorcode);
|
||||||
|
data->read_blob(&filedata);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class bdTimeStamp final : public bdTaskResult
|
class bdTimeStamp final : public bdTaskResult
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -222,52 +222,66 @@ namespace demonware
|
|||||||
|
|
||||||
void bdStorage::get_files(service_server* server, byte_buffer* buffer) const
|
void bdStorage::get_files(service_server* server, byte_buffer* buffer) const
|
||||||
{
|
{
|
||||||
uint32_t unk32_0;
|
std::string context;
|
||||||
uint32_t numfiles, count = 0;
|
buffer->read_string(&context);
|
||||||
uint64_t owner;
|
|
||||||
std::string game, platform;
|
|
||||||
|
|
||||||
buffer->read_string(&game);
|
printf("demonware: ctx '%s'\n", context.data());
|
||||||
buffer->read_uint32(&unk32_0);
|
|
||||||
buffer->read_uint64(&owner);
|
|
||||||
buffer->read_string(&platform);
|
|
||||||
buffer->read_uint64(&owner);
|
|
||||||
buffer->read_string(&platform);
|
|
||||||
buffer->read_uint32(&numfiles);
|
|
||||||
|
|
||||||
auto reply = server->create_reply(this->task_id());
|
uint32_t count;
|
||||||
|
buffer->read_uint32(&count);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < numfiles; i++)
|
std::vector<std::pair<uint64_t, std::string>> user_ctxs;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < count; i++)
|
||||||
{
|
{
|
||||||
std::string filename, data;
|
uint64_t user_id;
|
||||||
buffer->read_string(&filename);
|
std::string acc_type;
|
||||||
|
buffer->read_uint64(&user_id);
|
||||||
|
buffer->read_string(&acc_type);
|
||||||
|
|
||||||
const auto path = get_user_file_path(filename);
|
printf("demonware: user 0x%llX '%s'\n", user_id, acc_type.data());
|
||||||
if (!utils::io::read_file(path, &data))
|
user_ctxs.emplace_back(user_id, acc_type);
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(),
|
|
||||||
platform.data());
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto response = new bdFile;
|
|
||||||
response->owner_id = owner;
|
|
||||||
response->unk = 0;
|
|
||||||
response->platform = platform;
|
|
||||||
response->filename = filename;
|
|
||||||
response->data = data;
|
|
||||||
|
|
||||||
reply->add(response);
|
|
||||||
++count;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename.data(), platform.data());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == numfiles)
|
buffer->read_uint32(&count);
|
||||||
|
|
||||||
|
std::vector<std::string> filenames;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < count; i++)
|
||||||
|
{
|
||||||
|
std::string filename;
|
||||||
|
buffer->read_string(&filename);
|
||||||
|
printf("demonware: file '%s'\n", filename.data());
|
||||||
|
|
||||||
|
filenames.push_back(std::move(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reply = server->create_reply(this->task_id());
|
||||||
|
uint32_t available = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0u; i < filenames.size(); i++)
|
||||||
|
{
|
||||||
|
auto& name = filenames.at(i);
|
||||||
|
std::string filedata;
|
||||||
|
if (utils::io::read_file(get_user_file_path(name), &filedata))
|
||||||
|
{
|
||||||
|
auto* entry = new bdFileQueryResult;
|
||||||
|
entry->user_id = user_ctxs.at(i).first;
|
||||||
|
entry->platform = user_ctxs.at(i).second;
|
||||||
|
entry->filename = filenames.at(i);
|
||||||
|
entry->errorcode = 0;
|
||||||
|
entry->filedata = filedata;
|
||||||
|
reply->add(entry);
|
||||||
|
available++;
|
||||||
|
std::cout << "demonware: user file '" << name << "' dispatched.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "demonware: user file '" << name << "' not found.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == count)
|
||||||
{
|
{
|
||||||
reply->send();
|
reply->send();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user