Skip to content

Commit

Permalink
Update v0.20
Browse files Browse the repository at this point in the history
  • Loading branch information
kp7742 committed Apr 25, 2022
1 parent 8426065 commit 62f6c4e
Show file tree
Hide file tree
Showing 27 changed files with 368 additions and 112 deletions.
Binary file modified .DS_Store
Binary file not shown.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ Unreal Engine 4 Dumper for Android Devices, Dump Lib libUE4.so from Memory of Ga
- 2) Improved String Dumping Output
- 3) Fixed Verbose Output Not Showing while String Dumping
- 4) General Improvements to SDK Dumping
- v0.20:
- 1) Merged code from private repo
- 2) Few more improvements to SDK Dumping
- 3) Added Option to use pointer decryption
- 4) Added Support for PUBG New State Mobile
- 5) Added GWorld and GName Workaround for PUBGM Series
- 6) Offsets are not upto date with latest game versions so please update them yourself
- 7) And in the end, this is probably last and final update of UE4Dumper

## Features
- No need of Ptrace
Expand All @@ -67,6 +75,8 @@ Unreal Engine 4 Dumper for Android Devices, Dump Lib libUE4.so from Memory of Ga
- Tested on 32bit and 64bit PUBG Mobile Series

## Note
- Only for Educational or Learning Purpose.
- Project is Deprecated, No more updates in Future.
- Use 32bit and 64bit Version on Respected Arch of Game.
- Recommend to use in Training Mode for PUBG Mobile.
- Some Games with Modified UE4 Might not Dump Correctly.
Expand All @@ -83,7 +93,7 @@ Unreal Engine 4 Dumper for Android Devices, Dump Lib libUE4.so from Memory of Ga
```
./ue4dumper -h
UE4Dumper v0.19 <==> Made By KMODs(kp7742)
UE4Dumper v0.20 <==> Made By KMODs(kp7742)
Usage: ./ue4dumper <option(s)>
Dump Lib libUE4.so from Memory of Game Process and Generate structure SDK for UE4 Engine
Tested on PUBG Mobile Series and Other UE4 Based Games
Expand Down Expand Up @@ -113,6 +123,7 @@ Unreal Engine 4 Dumper for Android Devices, Dump Lib libUE4.so from Memory of Ga
--gworld <address> GWorld Pointer Address
--Other Args-----------------------------------------------------------------------------
--newue(Optional) Run in UE 4.23+ Mode
--ptrdec(Optional) Use Pointer Decryption Mode
--verbose(Optional) Show Verbose Output of Dumping
--derefgname(Optional) <true/false> De-Reference GNames Address(Default: true)
--derefguobj(Optional) <true/false> De-Reference GUObject Address(Default: false)
Expand Down
Binary file modified jni/.DS_Store
Binary file not shown.
Empty file modified jni/Android.mk
100755 → 100644
Empty file.
Empty file modified jni/Application.mk
100755 → 100644
Empty file.
Empty file modified jni/ELF/ElfReader.cpp
100755 → 100644
Empty file.
Empty file modified jni/ELF/ElfReader.h
100755 → 100644
Empty file.
Empty file modified jni/ELF/ElfRebuilder.cpp
100755 → 100644
Empty file.
Empty file modified jni/ELF/ElfRebuilder.h
100755 → 100644
Empty file.
Empty file modified jni/ELF/elf.h
100755 → 100644
Empty file.
Empty file modified jni/ELF/exelf.h
100755 → 100644
Empty file.
Empty file modified jni/ELF64/elf.h
100755 → 100644
Empty file.
Empty file modified jni/ELF64/fix.cpp
100755 → 100644
Empty file.
Empty file modified jni/ELF64/fix.h
100755 → 100644
Empty file.
79 changes: 66 additions & 13 deletions jni/FNames.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct WideStr {
}
}

free(source);

output[len] = L'\0';
return output;
}
Expand Down Expand Up @@ -82,23 +84,74 @@ string GetFNameFromID(uint32 index) {
return "None";
}
} else {
if (deRefGNames) {
kaddr TNameEntryArray = getPtr(getRealOffset(Offsets::GNames));
static kaddr TNameEntryArray;

kaddr FNameEntryArr = getPtr(
TNameEntryArray + ((index / 0x4000) * Offsets::PointerSize));
kaddr FNameEntry = getPtr(FNameEntryArr + ((index % 0x4000) * Offsets::PointerSize));
if (TNameEntryArray) {//As usual caching ;)
goto gotGName;
}

return ReadStr(FNameEntry + Offsets::FNameEntryToNameString, MAX_SIZE);
} else {
kaddr TNameEntryArray = getRealOffset(Offsets::GNames);
if (isPtrDec) {
if (isPGLite) {
uint32 modeSel = Read<uint32>(getRealOffset(Offsets::PGLEncSelect));
if (modeSel) {
kaddr blockSlice = getPtr(getRealOffset(Offsets::PGLBlockSlice1));
if (blockSlice) {
kaddr block = getPtr(blockSlice + (Offsets::PointerSize * 5));

kaddr FNameEntryArr = getPtr(
TNameEntryArray + ((index / 0x4000) * Offsets::PointerSize));
kaddr FNameEntry = getPtr(FNameEntryArr + ((index % 0x4000) * Offsets::PointerSize));
uint8 shift = Read<uint8>(getRealOffset(Offsets::PGLBlockShift));
kaddr offset = Offsets::PointerSize * (shift + 5);

return ReadStr(FNameEntry + Offsets::FNameEntryToNameString, MAX_SIZE);
kaddr encGName = getPtr(block + offset);

#if defined(__LP64__)
TNameEntryArray = encGName ^ 0x7878787878787878;
#else
TNameEntryArray = encGName ^ 0x78787878;
#endif
} else {
return "None";
}
} else {
kaddr blockSlice = getRealOffset(Offsets::PGLBlockSlice2);
if (blockSlice && Read<int>(blockSlice + 0x4)) {
kaddr block = getPtr(blockSlice + 0x8);

uint32 shift = Read<uint32>(blockSlice);
uint32 offset = (Offsets::PointerSize * 2) * (((shift - 0x64) / 0x3) - 1);

TNameEntryArray = getPtr(block + offset);
} else {
return "None";
}
}
} else {
kaddr blockSlice = getRealOffset(Offsets::GNames);
if (blockSlice) {
kaddr block = getPtr(blockSlice + 0x8);

uint32 shift = Read<uint32>(blockSlice);
uint32 offset = (Offsets::PointerSize * 2) * (((shift - 0x64) / 0x3) - 1);

TNameEntryArray = getPtr(block + offset);
} else {
return "None";
}
}
} else {
if (deRefGNames) {
TNameEntryArray = getPtr(getRealOffset(Offsets::GNames));
} else {
TNameEntryArray = getRealOffset(Offsets::GNames);
}
}

gotGName:
kaddr FNameEntryArr = getPtr(
TNameEntryArray + ((index / 0x4000) * Offsets::PointerSize));
kaddr FNameEntry = getPtr(
FNameEntryArr + ((index % 0x4000) * Offsets::PointerSize));

return ReadStr(FNameEntry + Offsets::FNameEntryToNameString, MAX_SIZE);
}
}

Expand Down Expand Up @@ -140,7 +193,7 @@ DumpBlocks423(ofstream &gname, uint32 &count, kaddr FNamePool, uint32 blockId, u
count++;
}
} else {
StrLength = -StrLength;
StrLength = -StrLength;//Negative lengths are for Unicode Characters
}

//Next
Expand Down
16 changes: 11 additions & 5 deletions jni/GUObjects.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ kaddr GetUObjectFromID(uint32 index) {
getRealOffset(Offsets::GUObjectArray) + Offsets::FUObjectArrayToTUObjectArray);
kaddr Chunk = getPtr(TUObjectArray + ((index / 0x10000) * Offsets::PointerSize));

return getPtr(Chunk + Offsets::FUObjectItemPad + ((index % 0x10000) * Offsets::FUObjectItemSize));
return getPtr(Chunk + Offsets::FUObjectItemPadd +
((index % 0x10000) * Offsets::FUObjectItemSize));
} else {
kaddr FUObjectArray;
if (deRefGUObjectArray) {
Expand All @@ -50,13 +51,18 @@ void DumpObjects(string out) {
if (obj.is_open()) {
cout << "Dumping Objects List: " << GetObjectCount() << endl;
clock_t begin = clock();
for (int32 i = 0; i < GetObjectCount(); i++) {
int32 ocount = GetObjectCount();
cout << "Objects Counts: " << setbase(10) << ocount << endl;
if (ocount < 10 || ocount > 999999) {
ocount = 300000;
}
for (int32 i = 0; i < ocount; i++) {
kaddr uobj = GetUObjectFromID(i);
if (UObject::isValid(uobj)) {
if (isVerbose) {
cout << setbase(10) << "[" << i << "]: " << UObject::getName(uobj) << endl;
cout << setbase(16) << "[0x" << i << "]: " << UObject::getName(uobj) << endl;
}
obj << setbase(10) << "[" << i << "]:" << endl;
obj << setbase(16) << "[0x" << i << "]:" << endl;
obj << "Name: " << UObject::getName(uobj).c_str() << endl;
obj << "Class: " << UObject::getClassName(uobj).c_str() << endl;
obj << "ObjectPtr: 0x" << setbase(16) << uobj << endl;
Expand All @@ -68,7 +74,7 @@ void DumpObjects(string out) {
obj.close();
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << count << " Valid Objects Dumped in " << elapsed_secs << "S" << endl;
cout << setbase(10) << count << " Valid Objects Dumped in " << elapsed_secs << "S" << endl;
}
}

Expand Down
Empty file modified jni/Log.h
100755 → 100644
Empty file.
61 changes: 53 additions & 8 deletions jni/Mem.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,17 @@ void Write(kaddr address, T data) {

template<typename T>
T *ReadArr(kaddr address, unsigned int size) {
T data[size];
T *ptr = data;
vm_readv(reinterpret_cast<void *>(address), reinterpret_cast<void *>(ptr), (sizeof(T) * size));
return ptr;
T *data = new T[size];
vm_readv(reinterpret_cast<void *>(address), reinterpret_cast<void *>(data), (sizeof(T) * size));
return data;
}

string ReadStr(kaddr address, unsigned int size) {
char *data = new char[size];
memset(data, '\0', size);

for (int i = 0; i < size; i++) {
vm_readv((void*)(address + (sizeof(char) * i)), (void*)(&data[0] + i), sizeof(char));
vm_readv((void *) (address + (sizeof(char) * i)), (void *) (&data[0] + i), sizeof(char));
if (data[i] == 0x0) {
break;
}
Expand All @@ -160,14 +159,23 @@ kaddr getPtr(kaddr address) {
return Read<kaddr>(address);
}

void HexDump(kaddr addr, int lines) {
int32 getInt32(kaddr address) {
return Read<int32>(address);
}

uint8 getUInt8(kaddr address) {
return Read<uint8>(address);
}

void HexDump(kaddr addr, int lines, kaddr offset = 0x0) {
printf("\n\t\t:Hex Dump:\n\n");
int ptr = 0;
for (int i = 0; i < lines; i++) {
kaddr curr = addr + (i * 8);
#if defined(__LP64__)
printf("0x%04lx: ", addr + (i * 8));
printf("0x%04lx - 0x%04lx: ", curr, (curr - addr) + offset);
#else
printf("0x%04x: ", addr + (i*8));
printf("0x%04x - 0x%04x: ", curr, (curr - addr) + offset);
#endif
for (int j = 0; j < 8; j++) {
#if defined(__LP64__)
Expand Down Expand Up @@ -249,4 +257,41 @@ void HexDump8B(kaddr addr, int lines) {
printf("\n");
}

// rotate left
template<class T>
T __ROL__(T value, int count) {
const uint nbits = sizeof(T) * 8;

if (count > 0) {
count %= nbits;
T high = value >> (nbits - count);
if (T(-1) < 0) // signed value
high &= ~((T(-1) << count));
value <<= count;
value |= high;
} else {
count = -count % nbits;
T low = value << (nbits - count);
value >>= count;
value |= low;
}
return value;
}

inline uint8 __ROL1__(uint8 value, int count) { return __ROL__((uint8) value, count); }

inline uint16 __ROL2__(uint16 value, int count) { return __ROL__((uint16) value, count); }

inline uint32 __ROL4__(uint32 value, int count) { return __ROL__((uint32) value, count); }

inline uint64 __ROL8__(uint64 value, int count) { return __ROL__((uint64) value, count); }

inline uint8 __ROR1__(uint8 value, int count) { return __ROL__((uint8) value, -count); }

inline uint16 __ROR2__(uint16 value, int count) { return __ROL__((uint16) value, -count); }

inline uint32 __ROR4__(uint32 value, int count) { return __ROL__((uint32) value, -count); }

inline uint64 __ROR8__(uint64 value, int count) { return __ROL__((uint64) value, -count); }

#endif //MEMORY_H
Loading

0 comments on commit 62f6c4e

Please sign in to comment.