#include "lib.h"
#ifdef DEBUG
#define LOG(fmt,args...) printf(fmt,##args)
#else
#define LOG(fmt,...) printf("")
#endif
#define ResolveMethod(ClassName, MethodName, Handle, MethodSignature) \
ClassName##__##MethodName = reinterpret_cast<decltype(ClassName##__##MethodName)>(symbolMethod.Find(Handle, MethodSignature)); \
if (nullptr == ClassName##__##MethodName) \
{ \
LOG("[-] Method not found: %s -> %s::%s\n", MethodSignature, #ClassName, #MethodName); \
fflush(stdout); \
}
namespace android
{
namespace detail
{
namespace ui
{
struct LayerStack
{
uint32_t id = UINT32_MAX;
};
enum class Rotation
{
Rotation0 = 0,
Rotation90 = 1,
Rotation180 = 2,
Rotation270 = 3
};
struct Size
{
int32_t width = -1;
int32_t height = -1;
};
struct DisplayState
{
LayerStack layerStack;
Rotation orientation = Rotation::Rotation0;
Size layerStackSpaceRect;
};
typedef int64_t nsecs_t; struct DisplayInfo
{
uint32_t w{0};
uint32_t h{0};
float xdpi{0};
float ydpi{0};
float fps{0};
float density{0};
uint8_t orientation{0};
bool secure{false};
nsecs_t appVsyncOffset{0};
nsecs_t presentationDeadline{0};
uint32_t viewportW{0};
uint32_t viewportH{0};
};
enum class DisplayType
{
DisplayIdMain = 0,
DisplayIdHdmi = 1
};
struct PhysicalDisplayId
{
uint64_t value;
};
}
struct String8;
struct LayerMetadata;
struct Surface;
struct SurfaceControl;
struct SurfaceComposerClientTransaction;
struct SurfaceComposerClient;
template <typename any_t>
struct StrongPointer
{
union
{
any_t *pointer;
char padding[sizeof(std::max_align_t)];
};
inline any_t *operator->() const { return pointer; }
inline any_t *get() const { return pointer; }
inline explicit operator bool() const { return nullptr != pointer; }
};
struct Functionals
{
struct SymbolMethod
{
void *(*Open)(const char *filename, int flag) = nullptr;
void *(*Find)(void *handle, const char *symbol) = nullptr;
int (*Close)(void *handle) = nullptr;
};
size_t systemVersion = 13;
void (*RefBase__IncStrong)(void *thiz, void *id) = nullptr;
void (*RefBase__DecStrong)(void *thiz, void *id) = nullptr;
void (*String8__Constructor)(void *thiz, const char *const data) = nullptr;
void (*String8__Destructor)(void *thiz) = nullptr;
void (*LayerMetadata__Constructor)(void *thiz) = nullptr;
void (*LayerMetadata__setInt32)(void *thiz, uint32_t key, int32_t value) = nullptr;
void (*SurfaceComposerClient__Constructor)(void *thiz) = nullptr;
void (*SurfaceComposerClient__Destructor)(void *thiz) = nullptr;
StrongPointer<void> (*SurfaceComposerClient__CreateSurface)(void *thiz, void *name, uint32_t w, uint32_t h, int32_t format, uint32_t flags, void *parentHandle, void *layerMetadata, uint32_t *outTransformHint) = nullptr;
StrongPointer<void> (*SurfaceComposerClient__CreateSurface_and9)(void *thiz, void *name, uint32_t w, uint32_t h, int32_t format, uint32_t flags, void *parentHandle, int32_t windowType, int32_t ownerUid) = nullptr;
StrongPointer<void> (*SurfaceComposerClient__GetInternalDisplayToken)() = nullptr;
StrongPointer<void> (*SurfaceComposerClient__GetBuiltInDisplay)(ui::DisplayType type) = nullptr;
int32_t (*SurfaceComposerClient__GetDisplayState)(StrongPointer<void> &display, ui::DisplayState *displayState) = nullptr;
int32_t (*SurfaceComposerClient__GetDisplayInfo)(StrongPointer<void> &display, ui::DisplayInfo *displayInfo) = nullptr;
std::vector<ui::PhysicalDisplayId> (*SurfaceComposerClient__GetPhysicalDisplayIds)() = nullptr;
StrongPointer<void> (*SurfaceComposerClient__GetPhysicalDisplayToken)(ui::PhysicalDisplayId displayId) = nullptr;
void (*SurfaceComposerClient__Transaction__Constructor)(void *thiz) = nullptr;
void *(*SurfaceComposerClient__Transaction__SetLayer)(void *thiz, StrongPointer<void> &surfaceControl, int32_t z) = nullptr;
void *(*SurfaceComposerClient__Transaction__SetTrustedOverlay)(void *thiz, StrongPointer<void> &surfaceControl, bool isTrustedOverlay) = nullptr;
int32_t (*SurfaceComposerClient__Transaction__Apply)(void *thiz, bool synchronous, bool oneWay) = nullptr;
int32_t (*SurfaceControl__Validate)(void *thiz) = nullptr;
StrongPointer<Surface> (*SurfaceControl__GetSurface)(void *thiz) = nullptr;
void (*SurfaceControl__DisConnect)(void *thiz) = nullptr;
Functionals(const SymbolMethod &symbolMethod)
{
void *handle = symbolMethod.Open("/system/lib64/libandroid.so",RTLD_NOW);
if(!handle){
printf("cannot open libandroid.so\n");
exit(-1) ;
}
std::string systemVersionString(128, 0);
systemVersionString.resize(__system_property_get("ro.build.version.release", systemVersionString.data()));
if (!systemVersionString.empty())
systemVersion = std::stoi(systemVersionString);
if (9 > systemVersion)
{
LOG("[-] Unsupported system version: %zu", systemVersion);
return;
}
static std::unordered_map<size_t, std::unordered_map<void **, const char *>> patchesTable = {
{
15,
{
{reinterpret_cast<void **>(&LayerMetadata__Constructor), "_ZN7android3gui13LayerMetadataC2Ev"},
{reinterpret_cast<void **>(&SurfaceComposerClient__CreateSurface), "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjiiRKNS_2spINS_7IBinderEEENS_3gui13LayerMetadataEPj"},
},
},
{
14,
{
{reinterpret_cast<void **>(&LayerMetadata__Constructor), "_ZN7android3gui13LayerMetadataC2Ev"},
{reinterpret_cast<void **>(&SurfaceComposerClient__CreateSurface), "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjiiRKNS_2spINS_7IBinderEEENS_3gui13LayerMetadataEPj"},
},
},
{
12,
{
{reinterpret_cast<void **>(&SurfaceComposerClient__Transaction__Apply), "_ZN7android21SurfaceComposerClient11Transaction5applyEb"},
},
},
{
11,
{
{reinterpret_cast<void **>(&SurfaceComposerClient__CreateSurface), "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjijPNS_14SurfaceControlENS_13LayerMetadataEPj"},
{reinterpret_cast<void **>(&SurfaceControl__GetSurface), "_ZNK7android14SurfaceControl10getSurfaceEv"},
},
},
{
10,
{
{reinterpret_cast<void **>(&SurfaceComposerClient__CreateSurface), "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjijPNS_14SurfaceControlENS_13LayerMetadataE"},
{reinterpret_cast<void **>(&SurfaceControl__GetSurface), "_ZNK7android14SurfaceControl10getSurfaceEv"},
},
},
{
9,
{
{reinterpret_cast<void **>(&SurfaceComposerClient__CreateSurface_and9), "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjijPNS_14SurfaceControlEii"},
{reinterpret_cast<void **>(&SurfaceComposerClient__GetBuiltInDisplay), "_ZN7android21SurfaceComposerClient17getBuiltInDisplayEi"},
{reinterpret_cast<void **>(&SurfaceControl__GetSurface), "_ZNK7android14SurfaceControl10getSurfaceEv"},
},
},
};
#ifdef __LP64__
auto libgui = symbolMethod.Open("/system/lib64/libgui.so", RTLD_LAZY);
auto libutils = symbolMethod.Open("/system/lib64/libutils.so", RTLD_LAZY);
#else
auto libgui = symbolMethod.Open("/system/lib/libgui.so", RTLD_LAZY);
auto libutils = symbolMethod.Open("/system/lib/libutils.so", RTLD_LAZY);
#endif
ResolveMethod(RefBase, IncStrong, libutils, "_ZNK7android7RefBase9incStrongEPKv");
ResolveMethod(RefBase, DecStrong, libutils, "_ZNK7android7RefBase9decStrongEPKv");
ResolveMethod(String8, Constructor, libutils, "_ZN7android7String8C2EPKc");
ResolveMethod(String8, Destructor, libutils, "_ZN7android7String8D2Ev");
ResolveMethod(LayerMetadata, Constructor, libgui, "_ZN7android13LayerMetadataC2Ev");
ResolveMethod(LayerMetadata, setInt32, libgui, "_ZN7android13LayerMetadata8setInt32Eji");
ResolveMethod(SurfaceComposerClient, Constructor, libgui, "_ZN7android21SurfaceComposerClientC2Ev");
ResolveMethod(SurfaceComposerClient, CreateSurface, libgui, "_ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8EjjijRKNS_2spINS_7IBinderEEENS_13LayerMetadataEPj");
ResolveMethod(SurfaceComposerClient, GetInternalDisplayToken, libgui, "_ZN7android21SurfaceComposerClient23getInternalDisplayTokenEv");
ResolveMethod(SurfaceComposerClient, GetDisplayState, libgui, "_ZN7android21SurfaceComposerClient15getDisplayStateERKNS_2spINS_7IBinderEEEPNS_2ui12DisplayStateE");
ResolveMethod(SurfaceComposerClient, GetDisplayInfo, libgui, "_ZN7android21SurfaceComposerClient14getDisplayInfoERKNS_2spINS_7IBinderEEEPNS_11DisplayInfoE");
ResolveMethod(SurfaceComposerClient, GetPhysicalDisplayIds, libgui, "_ZN7android21SurfaceComposerClient21getPhysicalDisplayIdsEv");
ResolveMethod(SurfaceComposerClient, GetPhysicalDisplayToken, libgui, "_ZN7android21SurfaceComposerClient23getPhysicalDisplayTokenENS_17PhysicalDisplayIdE");
ResolveMethod(SurfaceComposerClient__Transaction, Constructor, libgui, "_ZN7android21SurfaceComposerClient11TransactionC2Ev");
ResolveMethod(SurfaceComposerClient__Transaction, SetLayer, libgui, "_ZN7android21SurfaceComposerClient11Transaction8setLayerERKNS_2spINS_14SurfaceControlEEEi");
ResolveMethod(SurfaceComposerClient__Transaction, SetTrustedOverlay, libgui, "_ZN7android21SurfaceComposerClient11Transaction17setTrustedOverlayERKNS_2spINS_14SurfaceControlEEEb");
ResolveMethod(SurfaceComposerClient__Transaction, Apply, libgui, "_ZN7android21SurfaceComposerClient11Transaction5applyEbb");
ResolveMethod(SurfaceControl, Validate, libgui, "_ZNK7android14SurfaceControl8validateEv");
ResolveMethod(SurfaceControl, GetSurface, libgui, "_ZN7android14SurfaceControl10getSurfaceEv");
ResolveMethod(SurfaceControl, DisConnect, libgui, "_ZN7android14SurfaceControl10disconnectEv");
auto it = patchesTable.find(systemVersion);
fflush(stdout);
if (it != patchesTable.end())
{
for (const auto &[patchTo, signature] : patchesTable.at(systemVersion))
{
*patchTo = symbolMethod.Find(libgui, signature);
if (nullptr != *patchTo)
{
LOG("[-] Patch method found: %s\n", signature);
fflush(stdout);
continue;
}
LOG("[-] Patch method not found: %s\n", signature);
fflush(stdout);
}
}
symbolMethod.Close(libutils);
symbolMethod.Close(libgui);
}
static const Functionals &GetInstance(const SymbolMethod &symbolMethod = {.Open = dlopen, .Find = dlsym, .Close = dlclose})
{
static Functionals functionals(symbolMethod);
return functionals;
}
};
struct String8
{
char data[1024];
String8(const char *const string)
{
Functionals::GetInstance().String8__Constructor(data, string);
}
~String8()
{
Functionals::GetInstance().String8__Destructor(data);
}
operator void *()
{
return reinterpret_cast<void *>(data);
}
};
struct LayerMetadata
{
char data[1024];
LayerMetadata()
{
if (9 < Functionals::GetInstance().systemVersion)
{
Functionals::GetInstance().LayerMetadata__Constructor(data);
}
}
void setInt32(uint32_t key, int32_t value)
{
Functionals::GetInstance().LayerMetadata__setInt32(data, key, value);
}
operator void *()
{
if (9 < Functionals::GetInstance().systemVersion)
return reinterpret_cast<void *>(data);
else
return nullptr;
}
};
struct Surface
{
};
struct SurfaceControl
{
void *data;
SurfaceControl() : data(nullptr) {}
SurfaceControl(void *data) : data(data) {}
int32_t Validate()
{
if (nullptr == data)
return 0;
return Functionals::GetInstance().SurfaceControl__Validate(data);
}
Surface *GetSurface()
{
if (nullptr == data)
return nullptr;
auto result = Functionals::GetInstance().SurfaceControl__GetSurface(data);
return reinterpret_cast<Surface *>(reinterpret_cast<size_t>(result.pointer) + sizeof(std::max_align_t) / 2);
}
void DisConnect()
{
if (nullptr == data)
return;
Functionals::GetInstance().SurfaceControl__DisConnect(data);
}
void DestroySurface(Surface *surface)
{
if (nullptr == data || nullptr == surface)
return;
Functionals::GetInstance().RefBase__DecStrong(reinterpret_cast<Surface *>(reinterpret_cast<size_t>(surface) - sizeof(std::max_align_t) / 2), this);
DisConnect();
Functionals::GetInstance().RefBase__DecStrong(data, this);
}
};
struct SurfaceComposerClientTransaction
{
char data[1024];
SurfaceComposerClientTransaction()
{
Functionals::GetInstance().SurfaceComposerClient__Transaction__Constructor(data);
}
void *SetLayer(StrongPointer<void> &surfaceControl, int32_t z)
{
return Functionals::GetInstance().SurfaceComposerClient__Transaction__SetLayer(data, surfaceControl, z);
}
void *SetTrustedOverlay(StrongPointer<void> &surfaceControl, bool isTrustedOverlay)
{
return Functionals::GetInstance().SurfaceComposerClient__Transaction__SetTrustedOverlay(data, surfaceControl, isTrustedOverlay);
}
int32_t Apply(bool synchronous, bool oneWay)
{
if (12 >= Functionals::GetInstance().systemVersion)
return reinterpret_cast<int32_t (*)(void *, bool)>(Functionals::GetInstance().SurfaceComposerClient__Transaction__Apply)(data, synchronous);
else
return Functionals::GetInstance().SurfaceComposerClient__Transaction__Apply(data, synchronous, oneWay);
}
};
struct SurfaceComposerClient
{
char data[1024];
SurfaceComposerClient()
{
Functionals::GetInstance().SurfaceComposerClient__Constructor(data);
Functionals::GetInstance().RefBase__IncStrong(data, this);
}
SurfaceControl CreateSurface(const char *name, int32_t width, int32_t height, bool skipScrenshot)
{
void *parentHandle = nullptr;
String8 windowName(name);
LayerMetadata layerMetadata;
if (skipScrenshot && (Functionals::GetInstance().systemVersion == 10 || Functionals::GetInstance().systemVersion == 11))
{
layerMetadata.setInt32(2u, 441731);
}
uint32_t flags = 0;
if (skipScrenshot && Functionals::GetInstance().systemVersion >= 12)
{
flags |= 0x40;
}
if (12 <= Functionals::GetInstance().systemVersion)
{
static void *fakeParentHandleForBinder = nullptr;
parentHandle = &fakeParentHandleForBinder;
}
StrongPointer<void> result;
if (Functionals::GetInstance().systemVersion == 9)
{
int32_t windowType = -1;
int32_t ownerUid = -1;
if (skipScrenshot)
{
windowType = 441731;
}
result = Functionals::GetInstance().SurfaceComposerClient__CreateSurface_and9(data, windowName, width, height, 1, flags, parentHandle, windowType, ownerUid);
}
else if (Functionals::GetInstance().systemVersion >= 10)
{
result = Functionals::GetInstance().SurfaceComposerClient__CreateSurface(data, windowName, width, height, 1, flags, parentHandle, layerMetadata, nullptr);
}
if (12 <= Functionals::GetInstance().systemVersion)
{
static SurfaceComposerClientTransaction transaction;
transaction.SetTrustedOverlay(result, true);
transaction.Apply(false, true);
}
return {result.get()};
}
bool GetDisplayInfo(ui::DisplayState *displayInfo)
{
StrongPointer<void> defaultDisplay;
if (9 >= Functionals::GetInstance().systemVersion)
defaultDisplay = Functionals::GetInstance().SurfaceComposerClient__GetBuiltInDisplay(ui::DisplayType::DisplayIdMain);
else
{
if (14 > Functionals::GetInstance().systemVersion)
defaultDisplay = Functionals::GetInstance().SurfaceComposerClient__GetInternalDisplayToken();
else
{
auto displayIds = Functionals::GetInstance().SurfaceComposerClient__GetPhysicalDisplayIds();
if (displayIds.empty())
return false;
defaultDisplay = Functionals::GetInstance().SurfaceComposerClient__GetPhysicalDisplayToken(displayIds[0]);
}
}
if (nullptr == defaultDisplay.get())
return false;
if (11 <= Functionals::GetInstance().systemVersion)
{
return 0 == Functionals::GetInstance().SurfaceComposerClient__GetDisplayState(defaultDisplay, displayInfo);
}
else
{
ui::DisplayInfo realDisplayInfo{};
if (0 != Functionals::GetInstance().SurfaceComposerClient__GetDisplayInfo(defaultDisplay, &realDisplayInfo))
return false;
displayInfo->layerStackSpaceRect.width = realDisplayInfo.w;
displayInfo->layerStackSpaceRect.height = realDisplayInfo.h;
displayInfo->orientation = static_cast<ui::Rotation>(realDisplayInfo.orientation);
return true;
}
}
};
}
struct WindowSurface
{
ANativeWindow *win;
detail::SurfaceControl surface_control;
};
#define MAP_SIZE 10
static WindowSurface window_surface_map[MAP_SIZE] = {0};
static detail::SurfaceControl *get_window_surface(ANativeWindow *win)
{
for (int i = 0; i < MAP_SIZE; i++)
{
if (window_surface_map[i].win == win)
{
return &window_surface_map[i].surface_control;
}
}
return nullptr;
}
static void emplace_window_surface(ANativeWindow *win, detail::SurfaceControl surface)
{
auto surface_control = get_window_surface(win);
ANativeWindow *target = nullptr;
if (surface_control != nullptr)
target = win;
for (int i = 0; i < MAP_SIZE; i++)
{
if (window_surface_map[i].win == target)
{
window_surface_map[i].surface_control = surface;
break;
}
}
}
static void remove_window_surface(ANativeWindow *win)
{
for (int i = 0; i < MAP_SIZE; i++)
{
if (window_surface_map[i].win == win)
{
window_surface_map[i].win = nullptr;
break;
}
}
}
#undef MAP_SIZE
static detail::SurfaceComposerClient &GetComposerInstance()
{
static detail::SurfaceComposerClient surfaceComposerClient;
return surfaceComposerClient;
}
extern "C"
{
__attribute__((visibility("default"))) DisplayInfo greeting(){
printf("you will get a DisplayInfo for fun, which is {1,2,3}\n");
return DisplayInfo{1,2,3};
}
__attribute__((visibility("default"))) DisplayInfo get_display_info()
{
auto &surfaceComposerClient = GetComposerInstance();
detail::ui::DisplayState displayInfo{};
if (!surfaceComposerClient.GetDisplayInfo(&displayInfo))
return {};
DisplayInfo local_displayInfo{0};
int32_t local_orientation = static_cast<int32_t>(displayInfo.orientation);
int32_t local_abs_x = (displayInfo.layerStackSpaceRect.width > displayInfo.layerStackSpaceRect.height ? displayInfo.layerStackSpaceRect.width : displayInfo.layerStackSpaceRect.height);
int32_t local_abs_y = (displayInfo.layerStackSpaceRect.width < displayInfo.layerStackSpaceRect.height ? displayInfo.layerStackSpaceRect.width : displayInfo.layerStackSpaceRect.height);
if (local_orientation == 1 || local_orientation == 3)
{
local_displayInfo.width = local_abs_x;
local_displayInfo.height = local_abs_y;
}
else
{
local_displayInfo.width = local_abs_y;
local_displayInfo.height = local_abs_x;
}
local_displayInfo.orientation = local_orientation;
return local_displayInfo;
}
__attribute__((visibility("default"))) ANativeWindow *create_native_window(const char *name, int32_t width = -1, int32_t height = -1, bool skipScrenshot_ = false)
{
auto &surfaceComposerClient = GetComposerInstance();
while (-1 == width || -1 == height)
{
detail::ui::DisplayState displayInfo{};
if (!surfaceComposerClient.GetDisplayInfo(&displayInfo))
break;
width = displayInfo.layerStackSpaceRect.width;
height = displayInfo.layerStackSpaceRect.height;
break;
}
auto surfaceControl = surfaceComposerClient.CreateSurface(name, width, height, skipScrenshot_);
auto nativeWindow = reinterpret_cast<ANativeWindow *>(surfaceControl.GetSurface());
emplace_window_surface(nativeWindow, std::move(surfaceControl));
window_surface_map[0].win = nativeWindow;
window_surface_map[0].surface_control = std::move(surfaceControl);
return nativeWindow;
}
__attribute__((visibility("default"))) void destroy_native_window(ANativeWindow *nativeWindow)
{
auto surface_control = get_window_surface(nativeWindow);
if (surface_control == nullptr)
return;
surface_control->DestroySurface(reinterpret_cast<detail::Surface *>(nativeWindow));
remove_window_surface(nativeWindow);
}
}
}
#undef ResolveMethod
#undef LOG