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] Disable Hardware Breakpoint Detection
|
||||
- [x] Disable Integrity Checks
|
||||
- [ ] Demonware Emulation
|
||||
- [x] Demonware Emulation
|
||||
- [ ] Disable Anti-Debugging Mechanisms
|
||||
|
||||
## Download
|
||||
|
@ -481,6 +481,10 @@ namespace demonware
|
||||
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>(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
|
||||
|
@ -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
|
||||
{
|
||||
public:
|
||||
|
@ -222,52 +222,66 @@ namespace demonware
|
||||
|
||||
void bdStorage::get_files(service_server* server, byte_buffer* buffer) const
|
||||
{
|
||||
uint32_t unk32_0;
|
||||
uint32_t numfiles, count = 0;
|
||||
uint64_t owner;
|
||||
std::string game, platform;
|
||||
std::string context;
|
||||
buffer->read_string(&context);
|
||||
|
||||
buffer->read_string(&game);
|
||||
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);
|
||||
printf("demonware: ctx '%s'\n", context.data());
|
||||
|
||||
uint32_t count;
|
||||
buffer->read_uint32(&count);
|
||||
|
||||
std::vector<std::pair<uint64_t, std::string>> user_ctxs;
|
||||
|
||||
for (auto i = 0u; i < count; i++)
|
||||
{
|
||||
uint64_t user_id;
|
||||
std::string acc_type;
|
||||
buffer->read_uint64(&user_id);
|
||||
buffer->read_string(&acc_type);
|
||||
|
||||
printf("demonware: user 0x%llX '%s'\n", user_id, acc_type.data());
|
||||
user_ctxs.emplace_back(user_id, acc_type);
|
||||
}
|
||||
|
||||
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 (uint32_t i = 0; i < numfiles; i++)
|
||||
for (size_t i = 0u; i < filenames.size(); i++)
|
||||
{
|
||||
std::string filename, data;
|
||||
buffer->read_string(&filename);
|
||||
|
||||
const auto path = get_user_file_path(filename);
|
||||
if (!utils::io::read_file(path, &data))
|
||||
auto& name = filenames.at(i);
|
||||
std::string filedata;
|
||||
if (utils::io::read_file(get_user_file_path(name), &filedata))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(),
|
||||
platform.data());
|
||||
#endif
|
||||
continue;
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
if (available == count)
|
||||
{
|
||||
reply->send();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user