@@ -7,18 +7,19 @@ bool KittyInjector::init(pid_t pid, EKittyMemOP eMemOp)
77
88 _kMgr = std::make_unique<KittyMemoryMgr>();
99
10- if (!_kMgr->initialize (pid, eMemOp, false ))
10+ if (!_kMgr->initialize (pid, eMemOp, true ))
1111 {
1212 KITTY_LOGE (" KittyInjector: Failed to initialize kittyMgr." );
1313 return false ;
1414 }
1515
16+ _kMgr->trace .setAutoRestoreRegs (false );
17+
1618 bool isLocal64bit = !KittyMemoryEx::getMapsContain (getpid (), " /lib64/" ).empty ();
1719 bool isRemote64bit = !KittyMemoryEx::getMapsContain (pid, " /lib64/" ).empty ();
1820 if (isLocal64bit != isRemote64bit)
1921 {
20- KITTY_LOGE (" KittyInjector: Injector is %sbit but target app is %sbit." ,
21- isLocal64bit ? " 64" : " 32" , isRemote64bit ? " 64" : " 32" );
22+ KITTY_LOGE (" KittyInjector: Injector is %sbit but target app is %sbit." , isLocal64bit ? " 64" : " 32" , isRemote64bit ? " 64" : " 32" );
2223 return false ;
2324 }
2425
@@ -28,6 +29,8 @@ bool KittyInjector::init(pid_t pid, EKittyMemOP eMemOp)
2829 return false ;
2930 }
3031
32+ _soinfo_patch.init (_kMgr.get ());
33+
3134 _remote_dlopen = _kMgr->findRemoteOf (" dlopen" , (uintptr_t )&dlopen);
3235 if (!_remote_dlopen)
3336 {
@@ -59,7 +62,7 @@ bool KittyInjector::init(pid_t pid, EKittyMemOP eMemOp)
5962 return true ;
6063}
6164
62- injected_info_t KittyInjector::injectLibrary (std::string libPath, int flags, bool use_memfd_dl)
65+ injected_info_t KittyInjector::injectLibrary (std::string libPath, int flags, bool use_memfd_dl, bool hide )
6366{
6467 if (!_kMgr.get () || !_kMgr->isMemValid ())
6568 {
@@ -133,14 +136,46 @@ injected_info_t KittyInjector::injectLibrary(std::string libPath, int flags, boo
133136 }
134137 }
135138
139+ pt_regs bkup_regs;
140+ memset (&bkup_regs, 0 , sizeof (bkup_regs));
141+
142+ if (!_kMgr->trace .getRegs (&bkup_regs))
143+ {
144+ KITTY_LOGE (" injectLibrary: failed to backup registers." );
145+ return {};
146+ }
147+
136148 injected_info_t injected {};
137149
138150 if (libHdr.e_machine == kNativeEM )
151+ {
152+ if (hide)
153+ _soinfo_patch.before_dlopen_patch ();
154+
139155 injected = nativeInject (libFile, flags, canUseMemfd);
156+
157+ if (hide)
158+ _soinfo_patch.after_dlopen_patch ();
159+ }
140160 else
161+ {
141162 injected = emuInject (libFile, flags);
163+ }
164+
165+ KITTY_LOGI (" lib handle = %p" , (void *)injected.dl_handle );
142166
143- if (!injected.is_valid ())
167+ if (injected.is_valid ())
168+ {
169+ if (libHdr.e_machine == kNativeEM && hide)
170+ {
171+ hideSegmentsFromMaps (injected);
172+
173+ uintptr_t hide_init = injected.elfMap .elfScan .findSymbol (" hide_init" );
174+ KITTY_LOGI (" Calling hide_init -> %p" , (void *)hide_init);
175+ _kMgr->trace .callFunction (hide_init, 0 );
176+ }
177+ }
178+ else
144179 {
145180 KITTY_LOGE (" injectLibrary: failed )':" );
146181 KITTY_LOGE (" injectLibrary: calling dlerror..." );
@@ -165,6 +200,9 @@ injected_info_t KittyInjector::injectLibrary(std::string libPath, int flags, boo
165200 // cleanup
166201 _remote_syscall.clearAllocatedMaps ();
167202
203+ if (!_kMgr->trace .setRegs (&bkup_regs))
204+ KITTY_LOGE (" injectLibrary: failed to restore registers." );
205+
168206 return injected;
169207}
170208
@@ -196,7 +234,7 @@ injected_info_t KittyInjector::nativeInject(KittyIOFile& lib, int flags, bool us
196234 {
197235 std::string memfd_rand = KittyUtils::random_string (KittyUtils::randInt (5 , 12 ));
198236
199- info.name = memfd_rand;
237+ info.name = " /memfd: " + memfd_rand;
200238
201239 uintptr_t rmemfd_name = _remote_syscall.rmmap_str (memfd_rand);
202240 if (!rmemfd_name)
@@ -237,7 +275,7 @@ injected_info_t KittyInjector::nativeInject(KittyIOFile& lib, int flags, bool us
237275 info.dl_handle = _kMgr->trace .callFunction (_remote_dlopen_ext, 3 , rmemfd_name, flags, rdlextinfo);
238276 kINJ_WAIT ;
239277
240- info.elfMap = _kMgr->getElfBaseMap (memfd_rand );
278+ info.elfMap = _kMgr->getElfBaseMap (info. name );
241279
242280 return info.elfMap .isValid ();
243281 };
@@ -290,7 +328,8 @@ injected_info_t KittyInjector::emuInject(KittyIOFile& lib, int flags)
290328 // return (char *)&unk_64DF10 + 0xC670 * ns + qword_80C6C8;
291329 auto tryRemoteloadLibraryExt = [&](uint8_t ns_start, uint8_t ns_end) -> uintptr_t
292330 {
293- for (uint8_t i = ns_start; i <= ns_end; i++) {
331+ for (uint8_t i = ns_start; i <= ns_end; i++)
332+ {
294333 uintptr_t h = _kMgr->trace .callFunction ((uintptr_t )_nativeBridgeItf.loadLibraryExt , 3 , remoteLibPath, flags, i);
295334 kINJ_WAIT ;
296335
@@ -339,4 +378,49 @@ injected_info_t KittyInjector::emuInject(KittyIOFile& lib, int flags)
339378 info.elfMap = _kMgr->getElfBaseMap (lib.Path ());
340379
341380 return info;
381+ }
382+
383+ bool KittyInjector::hideSegmentsFromMaps (injected_info_t &inj_info)
384+ {
385+ if (!inj_info.is_valid ())
386+ {
387+ KITTY_LOGE (" hideSegmentsFromMaps: Invalid info." );
388+ return false ;
389+ }
390+
391+ if (inj_info.is_hidden || inj_info.elfMap .map .pathname .empty ())
392+ return true ;
393+
394+ // idea from https://github.com/RikkaApps/Riru/blob/master/riru/src/main/cpp/hide/hide.cpp
395+
396+ auto maps = KittyMemoryEx::getMapsContain (_kMgr->processID (), inj_info.elfMap .map .pathname );
397+ for (auto & it : maps)
398+ {
399+ KITTY_LOGI (" hideSegmentsFromMaps: Hiding segment %p - %p" , (void *)it.startAddress , (void *)it.endAddress );
400+
401+ // backup segment code
402+ auto bkup = _kMgr->memBackup .createBackup (it.startAddress , it.length );
403+
404+ _remote_syscall.rmunmap (it.startAddress , it.length );
405+ uintptr_t segment_new_map = _remote_syscall.rmmap_anon (it.startAddress , it.length , it.protection , false );
406+
407+ if (!IsValidRetPtr (segment_new_map))
408+ {
409+ KITTY_LOGE (" hideSegmentsFromMaps: Failed to re-map segment %p, error = %s" , (void *)it.startAddress , _remote_syscall.getRemoteError ().c_str ());
410+ return false ;
411+ }
412+
413+ // restore segment code
414+ bkup.Restore ();
415+ }
416+
417+ inj_info.name .clear ();
418+ inj_info.name .shrink_to_fit ();
419+
420+ inj_info.elfMap .map .pathname .clear ();
421+ inj_info.elfMap .map .pathname .shrink_to_fit ();
422+
423+ inj_info.is_hidden = true ;
424+
425+ return true ;
342426}
0 commit comments