nlib
oss/binarypatch/binarypatch.cpp

BsDiffZ()によるバイナリパッチの作成、及びBsPatchZ()によるパッチの適用を説明するサンプルです。

#include <string.h>
#if defined(CAFE) || defined(NN_PLATFORM_CTR)
#endif
static UniquePtr<unsigned char[]> g_OldData;
static size_t g_OldDataSize;
static UniquePtr<unsigned char[]> g_NewData;
static size_t g_NewDataSize;
static ReallocOutputStream::UniquePtrType g_PatchData;
static size_t g_PatchDataSize;
// Generates the old data.
static bool SetupOldData() {
nlib_printf("setup oldData\n");
g_OldData.reset(new(std::nothrow) unsigned char[1024 * 128]);
if (!g_OldData) return false;
for (size_t i = 0; i < 1024 * 128; ++i) {
g_OldData[i] = static_cast<unsigned char>(i % 256);
}
g_OldDataSize = 1024 * 128;
nlib_printf("oldData size = %" PRIuS " bytes\n", g_OldDataSize);
return true;
}
// Generates the new data.
static bool SetupNewData() {
nlib_printf("setup newData\n");
g_NewData.reset(new(std::nothrow) unsigned char[1024 * 1024]);
if (!g_NewData) return false;
for (size_t i = 0; i < 1024 * 1024; ++i) {
g_NewData[i] = static_cast<unsigned char>(255 - i % 256);
}
g_NewDataSize = 1024 * 1024;
nlib_printf("newData size = %" PRIuS " bytes\n", g_NewDataSize);
return true;
}
static bool MakeBsDiffZ() {
// Creates the patch from the old data to the new data.
// You can also create a patch by using bsdiff_z.exe on PCs.
nlib_printf("BsDiffZ()....\n");
ReallocOutputStream ostr;
g_OldData.get(), g_OldDataSize, g_NewData.get(), g_NewDataSize);
if (!nlib_is_error(e)) {
g_PatchDataSize = ostr.Release(&g_PatchData);
nlib_printf("patch size = %" PRIuS " bytes\n", g_PatchDataSize);
return true;
} else {
nlib_printf("BsDiffZ() failed\n");
return false;
}
}
static bool ApplyBsPatchZ() {
// Before you apply the patch,
// you have to place the old data and the patch for it on the memory.
// You can also apply a patch by using bspatch_z.exe on PCs.
nlib_printf("BsPatchZ()....\n");
ReallocOutputStream ostr;
g_OldData.get(), g_OldDataSize, g_PatchData.get(), g_PatchDataSize);
if (!nlib_is_error(e)) {
ReallocOutputStream::UniquePtrType result;
size_t resultSize = ostr.Release(&result);
nlib_printf("Checking the data .... ");
if (resultSize == g_NewDataSize &&
memcmp(g_NewData.get(), result.get(), resultSize) == 0) {
nlib_printf("success\n");
return true;
} else {
nlib_printf("fail\n");
return false;
}
} else {
nlib_printf("BsPatchZ() failed\n");
return false;
}
}
//
// bsdiff in nlib uses nmalloc/nfree in libnx_oss.a.
// You have to link libnx_oss.a, and set up nmalloc.
//
#if defined(CAFE) || defined(NN_PLATFORM_CTR)
#ifdef NLIB_HAS_VIRTUALMEMORY
extern "C" const NMallocSettings g_NMallocSettings = { NULL, 1024 * 1024 * 16, 0 };
#else
const size_t heapmem_size = 1024 * 1024 * 16;
NLIB_ALIGNAS(4096) static char heapmem[heapmem_size];
extern "C" const NMallocSettings g_NMallocSettings = { heapmem, heapmem_size, 0 };
#endif
#endif
bool SampleMain(int, char**) {
return SetupOldData() && SetupNewData() && MakeBsDiffZ() && ApplyBsPatchZ();
}
NLIB_MAINFUNC