diff --git a/NXTools.sln b/NXTools.sln index a231123..df725a3 100644 --- a/NXTools.sln +++ b/NXTools.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcrypto", "lib\crypto\cry EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnx", "lib\nx\nx.vcxproj", "{91BA9E79-8242-4F7D-B997-0DFEC95EA22B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ncatool", "programs\ncatool\ncatool.vcxproj", "{7DA88C6F-4470-495D-995A-4F633F3370C1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -41,6 +43,14 @@ Global {91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x64.Build.0 = Release|x64 {91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x86.ActiveCfg = Release|Win32 {91BA9E79-8242-4F7D-B997-0DFEC95EA22B}.Release|x86.Build.0 = Release|Win32 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x64.ActiveCfg = Debug|x64 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x64.Build.0 = Debug|x64 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x86.ActiveCfg = Debug|Win32 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Debug|x86.Build.0 = Debug|Win32 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x64.ActiveCfg = Release|x64 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x64.Build.0 = Release|x64 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x86.ActiveCfg = Release|Win32 + {7DA88C6F-4470-495D-995A-4F633F3370C1}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/makefile b/makefile index e69de29..2e12b4c 100644 --- a/makefile +++ b/makefile @@ -0,0 +1,11 @@ +main: build + +rebuild: clean build + +build: + cd lib && $(MAKE) && cd .. + cd programs && $(MAKE) && cd .. + +clean: + cd lib && $(MAKE) clean && cd .. + cd programs && $(MAKE) clean && cd .. \ No newline at end of file diff --git a/programs/makefile b/programs/makefile new file mode 100644 index 0000000..f5cc652 --- /dev/null +++ b/programs/makefile @@ -0,0 +1,13 @@ +PROGS = ncatool + +main: build + +rebuild: clean build + +build: + mkdir -p "../bin" + @$(foreach prog,$(PROGS), cd $(prog) && $(MAKE) && cd ..;) + +clean: + @$(foreach prog,$(PROGS), cd $(prog) && $(MAKE) clean && cd ..;) + #rm -rf "../bin" \ No newline at end of file diff --git a/programs/ncatool/main.cpp b/programs/ncatool/main.cpp new file mode 100644 index 0000000..7f46540 --- /dev/null +++ b/programs/ncatool/main.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include + +const size_t kNcaSectorSize = 0x200; + +void initNcaCtr(u8 ctr[crypto::aes::kAesBlockSize], u32 generation) +{ + memset(ctr, 0, crypto::aes::kAesBlockSize); + for (size_t i = 0; i < 4; i++) + { + ctr[7 - i] = (generation >> i * 8) & 0xff; + } +} + +void hexDump(const u8* data, size_t len) +{ + for (size_t i = 0; i < len; i++) + { + printf("%02X", data[i]); + } +} + +void decryptNcaSectorXts(const fnd::MemoryBlob& nca, u8 out[kNcaSectorSize], size_t sector, const u8* key1, const u8* key2) +{ + u8 tweak[crypto::aes::kAesBlockSize]; + crypto::aes::AesXtsMakeTweak(tweak, sector); + crypto::aes::AesXtsDecryptSector(nca.data() + sector*kNcaSectorSize, kNcaSectorSize, key1, key2, tweak, out); +} + +void decryptNcaSectorCtr(const fnd::MemoryBlob& nca, u8 out[kNcaSectorSize], size_t sector, const u8* key) +{ + u8 ctr[crypto::aes::kAesBlockSize]; + initNcaCtr(ctr, 0); + crypto::aes::AesIncrementCounter(ctr, (sector*kNcaSectorSize)/crypto::aes::kAesBlockSize, ctr); + crypto::aes::AesCtr(nca.data() + sector*kNcaSectorSize, kNcaSectorSize, key, ctr, out); +} + +void dumpNcaSector(u8 out[kNcaSectorSize]) +{ + for (size_t j = 0; j < kNcaSectorSize / crypto::aes::kAesBlockSize; j++) + { + hexDump(out + j * crypto::aes::kAesBlockSize, crypto::aes::kAesBlockSize); + printf("\n"); + } +} + +int main(int argc, char** argv) +{ + if (argc < 2) + { + printf("usage: ncatool \n"); + return 1; + } + + fnd::MemoryBlob nca; + fnd::FileIO::ReadFile(argv[1], nca); + + u8 sector[kNcaSectorSize]; + + // nca test + if (argc == 2) + { + decryptNcaSectorXts(nca, sector, 1, nx::crypto::aes::nca_header_key[0], nx::crypto::aes::nca_header_key[1]); + + NcaHeader hdr; + hdr.importBinary(sector); + + printf("NCA Header\n"); + printf(" Size: 0x%" PRIx64 "\n", hdr.getNcaSize()); + printf(" ProgID: 0x%016" PRIx64 "\n", hdr.getProgramId()); + printf(" Unk0: 0x%" PRIx32 "\n", hdr.getUnk()); + printf(" Sections:\n"); + for (size_t i = 0; i < hdr.getSections().size(); i++) + { + const NcaHeader::sSection& section = hdr.getSections()[i]; + printf(" %lu:\n", i); + printf(" Start Blk: %" PRId32 "\n", section.start_blk); + printf(" End Blk: %" PRId32 "\n", section.end_blk); + printf(" Offset: 0x%" PRIx64 "\n", section.offset); + printf(" Size: 0x%" PRIx64 "\n", section.size); + printf(" KeyType: 0x%02x\n", section.key_type); + printf(" Hash: "); + hexDump(section.hash.bytes, crypto::sha::kSha256HashLen); + printf("\n"); + } + printf(" AES Keys:\n"); + for (size_t i = 0; i < hdr.getAesKeys().size(); i++) + { + printf(" %lu: ", i); + hexDump(hdr.getAesKeys()[i].key, crypto::aes::kAes128KeySize); + printf("\n"); + } + + + } + + return 0; +} \ No newline at end of file diff --git a/programs/ncatool/makefile b/programs/ncatool/makefile new file mode 100644 index 0000000..117d52e --- /dev/null +++ b/programs/ncatool/makefile @@ -0,0 +1,39 @@ +# Sources +SRC_DIR = . +OBJS = $(foreach dir,$(SRC_DIR),$(subst .cpp,.o,$(wildcard $(dir)/*.cpp))) $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c))) + +#local dependencies +DEPENDS = nx crypto fnd + +LIB_DIR = ../../lib + +LIBS = -L"$(LIB_DIR)" $(foreach dep,$(DEPENDS), -l"$(dep)") +INCS = -I"$(LIB_DIR)/" + +OUTPUT = ../../bin/$(shell basename $(CURDIR)) + +# Compiler Settings +CXXFLAGS = -std=c++11 $(INCS) -D__STDC_FORMAT_MACROS -Wall -Wno-unused-but-set-variable -Wno-unused-value +ifeq ($(OS),Windows_NT) + # Windows Only Flags/Libs + CC = x86_64-w64-mingw32-gcc + CXX = x86_64-w64-mingw32-g++ + CFLAGS += + CXXFLAGS += + LIBS += -static +else + # *nix Only Flags/Libs + CFLAGS += + CXXFLAGS += + LIBS += +endif + +all: build + +rebuild: clean build + +build: $(OBJS) + $(CXX) $(OBJS) $(LIBS) -o $(OUTPUT) + +clean: + rm -rf $(OBJS) $(OUTPUT) \ No newline at end of file diff --git a/programs/ncatool/ncatool.vcxproj b/programs/ncatool/ncatool.vcxproj new file mode 100644 index 0000000..669f303 --- /dev/null +++ b/programs/ncatool/ncatool.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7DA88C6F-4470-495D-995A-4F633F3370C1} + ncatool + 10.0.15063.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + C:\Users\jkrca\Source\Repos\NXTools\lib + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/programs/ncatool/ncatool.vcxproj.filters b/programs/ncatool/ncatool.vcxproj.filters new file mode 100644 index 0000000..0d8d9e4 --- /dev/null +++ b/programs/ncatool/ncatool.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file