Comments (23)
I am pretty sure it does not exists on iOS, as they call it "ADISetAndroidID". You could try to pass the same message to vdfut768ig
(which is the function doing all the logic in CoreADI), but they may not use the same convention/magic values for the arguments.
from provision.
I don't quite understand... I found that AKADIProxy exists in the AKD program
But... this symbol is in CoreADI, do I mean akd references it
from provision.
Yeah AKADIProxy provides the same features as StoreServicesCore on Android, (and some of them are in StoreServices on iOS too). But the underlying CoreADI framework implementation is different. They are seemingly not derived from the same source code. To my knowledge, there are at least 5 distinct CoreADI libraries, and maybe even more anisette implementations.
from provision.
Btw, if you want to try, you might want to call that vdfut768ig
with the magic number of the function you are looking for. I haven't tried, and it might not work if they changed all the magic numbers across platforms, but if it does, you will get -45019
(unknown function) if the function does not exist, and -4500x
(invalid parameter) if it has been implemented but you provided the wrong arguments.
from provision.
My idea is to use Unidbg to call and generate OTP. If possible, I want to use AKAppleIDCodeGenerator
to generate verification code, but many test results have shown that it cannot be implemented on libstoreservicescore
from provision.
And calling AKADIProxy
through Unidbg loading/System/Library/PrivateFrameworks/AuthKit.framework/akd
also encountered some kind of error, seemingly due to its use of process communication resulting in -45016
error
from provision.
Oh... I seem to have found my solution, thank you for your help!
from provision.
By the way, if you know what was causing 45016, that would be useful since I try to document every ADI error code
from provision.
The reason for the occurrence of -45016
seems to be due to the failure of this system call
十二月 10, 2023 11:06:28 下午 com.github.unidbg.ios.ARM64SyscallHandler mach_msg_trap
警告: mach_msg_trap header=MachMsgHeader(unidbg@0xfbffffbd0) (24 bytes) {
int msgh_bits@0x0=0x80001513
int msgh_size@0x4=0x0001
int msgh_remote_port@0x8=0x0000
int msgh_local_port@0xC=0x0004
int msgh_voucher_port@0x10=0x0000
int msgh_id@0x14=0x04B0
}, size=24, lr=RX@0x100521b0c[libsystem_kernel.dylib]0x1b0c
I understand from this information that /System/Library/PrivateFrameworks/AuthKit.framework/akd
does not have any substantial Otp calculations
from provision.
The analysis of CoreADI
in the future may be a significant challenge for me
from provision.
I can give you some help on Discord if you want
from provision.
AKAppleIDCodeGenerator
@shanling2016 could you please tell if you have found a way to generate otp code as from AKAppleIDCodeGenerator.generateLoginCode()? Is this based on anisette otp base64 data (X-Apple-I-MD) or special call to adid is needed?
from provision.
AKAppleIDCodeGenerator
@shanling2016 could you please tell if you have found a way to generate otp code as from AKAppleIDCodeGenerator.generateLoginCode()? Is this based on anisette otp base64 data (X-Apple-I-MD) or special call to adid is needed?
I think it is based on a special call to adid
, which can be verified by deleting or renaming the adid
file. Before that, you need to kill the process first
from provision.
@shanling2016 @Dadoum it is certain,
Some observations regarding the CoreADI framework in macOS:
- The CoreADI framework isn't dynamically used (no instances of
dlopen
ordlsym
). Instead, it's statically linked into the ADID executable daemon found at/System/Library/PrivateFrameworks/CoreADI.framework/adid
. Interestingly, CoreADI is not compiled for Apple Silicon as it lacks an ARM64 slice. - The ADID daemon is heavily obfuscated and doesn't export worker functions like
vdfut768ig
orcvu8io98wun
. Managed bylaunchd
, it's shielded withPT_DENY_ATTACH
. To attach a debugger, one may need to delve into kernel-level debugging... - IPC: Libraries exposing external symbols (e.g.,
aslgmuibau
inAuthKit.framework/akd
,AOSKit.framework
,AppleMediaServices.framework
) communicate with ADID using low-level IPC, specifically Mach Ports with MIG (refer tomach_msg
,mig_get_reply_port
,NDR_record
). The code paths leading up tomach_msg
are obfuscated. ADID registers its port usingbootstrap_check_in
with namecom.apple.adid
and processes messages in a run loop created withCFMachPortCreateRunLoopSource
.
Message for generating a login code might look something like this (with msgh_id 1200 or 1300):
typedef struct {
mach_msg_header_t header; // Mach message header, 4 bytes
int v13; // Custom field, 4 bytes
int64_t v14; // Custom field, 8 bytes (possibly a 64-bit integer or pointer)
int v15; // Custom field, 4 bytes
int v16; // Custom field, 4 bytes
NDR_record_t NDR; // Network Data Representation record, 32 bytes
int v18; // Custom field, 4 bytes
} my_mach_msg_t;
When attempting to trace register activity with LLDB and Frida, I couldn't locate any references to the generated code near the mach_msg
calls. Significant logic might be hidden within the wrappers, or maybe I was observing the wrong registers.
A solution for macOS might be loading both libraries and using DYLD_INTERPOSE stubs to add a shim for Mach messaging. But how difficult would it be to emulate in Unicorn or anything else? Or maybe repack for Darling on Linux?
Script to generate 2fa login code from another process:
#/usr/bin/osascript -l JavaScript -i
ObjC.bindFunction('dlopen', ['void*', ['char*', 'int']]);
$.dlopen('/System/Library/PrivateFrameworks/AuthKit.framework/Versions/A/Support/akd', 0xa);
const AKAppleIDCodeGenerator = $.NSClassFromString($.NSString.alloc.initWithUTF8String('AKAppleIDCodeGenerator'));
AKAppleIDCodeGenerator.generateLoginCode(undefined);
sudo lsmp -p $(pgrep osascript) | grep adid # confirm IPC for launched script
sudo fs_usage | grep adi
21:26:33 lstat64 private/var/db/.AppleSetupUser 0.000031 adid
21:26:33 lstat64 private/var/setup>>>>>>> 0.000008 adid
21:26:33 lstat64 private/var/db/fpsd/adi 0.000026 adid
21:26:33 lstat64 private/var/db/fpsd/adi/adi-gb 0.000022 adid
21:26:33 getxattr private/var/db/fpsd/adi 0.000069 adid
21:26:33 umask 0.000001 adid
21:26:33 open private/var/db/fpsd/adi/adi-gb.lck 0.000066 adid
21:26:33 umask 0.000001 adid
21:26:33 fstat64 0.000005 adid
21:26:33 fcntl 0.000004 adid
21:26:33 statfs64 /private/var/db/fpsd/adi/adi-gb.lck 0.000011 adid
21:26:33 fcntl 0.000006 adid
21:26:33 lstat64 private/var/db/fpsd/adi/adi.pb 0.000013 adid
21:26:33 lstat64 private/var/db/.AppleSetupUser 0.000007 adid
21:26:33 lstat64 private/var/setup>>>>>>> 0.000005 adid
21:26:33 fcntl 0.000003 adid
21:26:33 close 0.000006 adid
from provision.
@xoridius I mostly figured out how calls to vdfut768ig
work.
The message structure you gave reminds me of the structure of a vdfut768ig
call:
typedef struct {
mach_msg_header_t header;
int v13; // Magic number referring to the function called?
int64_t v14; // Pointer to the ADICall structure. Size of it is max(8 + inputSize, outputSize)
int v15; // Input size
int v16; // Output size
NDR_record_t NDR; // ...
int v18; // ...
} my_mach_msg_t;
And an ADICall is made of a data encryption type int (telling how the following data is encrypted. It's generally 1 or 2. 2 is the unencrypted type, if you want to try to make a call), then the remaining is encrypted accordingly. Decrypted, the following fields are an unknown int (which is constant set to 1) and then the arguments in order. Then, after the call, the ADICall structure is overwritten and the data is replaced by the output, which generally consists of an int (and thus the output size is set to 4), which is the return code of the call.
from provision.
@xoridius do you have a discord account?
from provision.
After further investigation, no, Sph98paBcz
doesn't exist on macOS, and is not implemented in the executable. Sorry.
from provision.
After testing, it was found that in lower versions of OSX systems, the OTP challenge was carried out through akd
dynamic linking, which also includes AKAppleIDCodeGenerator
, which may serve as an entry point
from provision.
- Which version of OSX are you referring to?
- Does this OSX version allow generating 2FA codes from the Settings app? This is particularly interesting considering the Apple support page mentions that "trusted devices running iOS 9 and later, OS X El Capitan and later, etc., display the verification code automatically on your trusted devices". And akd from iOS 9.3.6 13G37 year 2019 already relies on adid daemon.
- Does akd use
vdfut768ig
? What's the calling convention?
Some magic numbers for calls to test:
ADIGenerateCode
: 0x385b2ce8 (generate 2FA login code)ADIOTPRequest
: 0xcfe0b46aADIGetIDMSRouting
: 0x85fe63b0AKADIProxy.isMachineProvisioned
: 0xb0eda7af
from provision.
@xoridius
I found dlopen loading CoreADI
in akd
in macOS 10.12.
The following is the data I captured through Frida
{
"base": "0x1093ae000",
"name": "CoreADI",
"path": "/System/Library/PrivateFrameworks/CoreADI.framework/CoreADI",
"size": 1503232
}
from provision.
@xoridius
Do you know the magical number to overload adi.pb with adid?
I hope to switch between different devices by modifying the adi.pb file, but Every time we need to restart the adid process, it's really too slow
Before that, I also tried writing code using xcode to send messages to com.apple.adid
, but…… it told me 0x1000000F "Invalid msg type specification"
bootstrap_look_up(bootstrapPort, "com.apple.adid", &port);
message.header.msgh_bits = 0x80131513;
message.header.msgh_size = 0;
message.header.msgh_remote_port = port;
message.header.msgh_local_port = mig_get_reply_port();;
message.header.msgh_id = 1200;
message.header.msgh_voucher_port = MACH_PORT_NULL;
/* Ignoring partial code */
mach_msg_return_t res = mach_msg((mach_msg_header_t*)&message, MACH_SEND_MSG, sizeof(message), 0, 0, 0, 0);
from provision.
@shanling2016 oh nice, that's Sierra, right? I was about to check High Sierra, looking for working boot image.
Not sure about magic code to reset adi.pb, but maybe eraseProvisioningForDSID will work? Can get those.
@interface AKADIProxy : NSObject
+(int)getIDMSRoutingInfo:(*NSUInteger)arg0 forDSID:(NSUInteger)arg1 ;
+(int)setIDMSRoutingInfo:(NSUInteger)arg0 forDSID:(NSUInteger)arg1 ;
+(int)requestOTPForDSID:(NSUInteger)arg0 outMID:(*char *)arg1 outMIDSize:(*unsigned int)arg2 outOTP:(*char *)arg3 outOTPSize:(*unsigned int)arg4 ;
+(int)dispose:(*void)arg0 ;
+(int)isMachineProvisioned:(NSUInteger)arg0 ;
+(int)startProvisioningWithDSID:(NSUInteger)arg0 SPIM:(char *)arg1 SPIMLength:(unsigned int)arg2 outCPIM:(*char *)arg3 outCPIMLength:(*unsigned int)arg4 outSession:(*unsigned int)arg5 ;
+(int)endProvisioningWithSession:(unsigned int)arg0 PTM:(char *)arg1 PTMLength:(unsigned int)arg2 TK:(char *)arg3 TKLength:(unsigned int)arg4 ;
+(int)destroyProvisioningSession:(unsigned int)arg0 ;
+(int)synchronizeWithDSID:(NSUInteger)arg0 SIM:(char *)arg1 SIMLength:(unsigned int)arg2 outMID:(*char *)arg3 outMIDLength:(*unsigned int)arg4 outSRM:(*char *)arg5 outSRMLength:(*unsigned int)arg6 ;
+(int)eraseProvisioningForDSID:(NSUInteger)arg0 ;
@end
Do you have discord? (Contact me at @bfmxor
)
from provision.
#import <mach/mach.h>
#import <bootstrap.h>
typedef struct {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_ool_descriptor_t ool_ports;
NDR_record_t NDR;
uint32_t p1;
} adi_mach_msg_t;
unsigned long ADIGenerateCode(void) {
mach_port_t p = MACH_PORT_NULL;
bootstrap_look_up(bootstrap_port, "com.apple.adid", &p);
printf("bootstrap_look_up(com.apple.adid)=%d\n", p);
adi_mach_msg_t *m = malloc(64);
m->header.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
m->header.msgh_size = 0;
m->header.msgh_local_port = mig_get_reply_port();
m->header.msgh_remote_port = p;
m->header.msgh_id = 1200;
m->header.msgh_voucher_port = 0;
m->body.msgh_descriptor_count = 1;
char cmd[] = {
0x00, 0x00, 0x00, 0x01, 0x38, 0x5b, 0x2c, 0xe8,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe
};
m->ool_ports.address = &cmd;
m->ool_ports.deallocate = 0;
m->ool_ports.copy = MACH_MSG_VIRTUAL_COPY;
m->ool_ports.pad1 = 0;
m->ool_ports.type = MACH_MSG_OOL_DESCRIPTOR;
m->ool_ports.size = 20;
m->NDR.mig_vers = 0;
m->NDR.if_vers = 0;
m->NDR.reserved1 = 0;
m->NDR.mig_encoding = 0;
m->NDR.int_rep = 1;
m->NDR.char_rep = 0;
m->NDR.float_rep = 0;
m->NDR.reserved2 = 0;
m->p1 = 0x00000014;
mach_msg_option_t option = MACH_SEND_MSG | MACH_RCV_MSG;
mach_msg_size_t send_size = 56;
mach_msg_size_t rcv_size = 64;
mach_port_name_t rcv_name = mig_get_reply_port();
mach_msg_header_t *msg = (mach_msg_header_t *)m;
mach_msg_return_t ret = mach_msg(msg, option, send_size, rcv_size, rcv_name, 0, 0);
if (ret == MACH_SEND_INVALID_DEST) {
return -1;
}
unsigned long value = OSReadSwapInt64(m->ool_ports.address, 0);
printf("ADIGenerateCode %ld\n", value);
return value;
}
from provision.
Related Issues (20)
- Anisette_server crashes on Apple Silicon Linux - loading openssl: unknown version for init HOT 4
- loading openssl: unknown version for init HOT 1
- Build failed HOT 7
- Unable to run on Raspberry Pi5 (armv7) HOT 2
- Unable to run o Raspberry Pi 4 Model B Rev 1.5 (ARMv8) HOT 6
- docker: Couldn't resolve host name HOT 1
- anisette-server seg fault on armv7 HOT 2
- Docker time error HOT 6
- Raspbian 64-bit Anisette Server Execution Error HOT 7
- Unable To Bind Websocket HOT 3
- An error occurred. There’s an error above. Please fix it to continue. HOT 5
- Segmentation Fault Raspberry PI Model 2 B HOT 8
- Hg
- Sidestore
- docker volume seem to not work, maybe due to permissions HOT 1
- it just restarts and lags my server HOT 2
- Render not allowing the creation of the service HOT 7
- Ii
- Provision doesn't work on Apple Silicon macs (bus error) HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from provision.