__text:1000025B8 ; __int64 __fastcall start(int, char **) __text:1000025B8 public start __text:1000025B8 start proc near ... __text:100002639 mov qword ptr cs:xmmword_1000139A0, rcx __text:100002640 lea r15, aAbpidicmwwsosx ; "abPIdicmwWsoSxfrCMET:t:l:R:B:" __text:100002647 lea r12, dword_10000346C ... __text:100002876 mov edi, ebx ; int __text:100002878 mov rsi, r14 ; char ** __text:10000287B mov rdx, r15 ; char * __text:10000287E call _getopt __text:100002883 lea ecx, [rax-42h]
__text:100003D20 take_the_screenshot proc near ... __text:100003D80 cmp cs:byte_100012553, 0 __text:100003D87 jnz short loc_100003D8E __text:100003D89 call playTheScreenshotSound
__text:100002E67 jz loc_100003130 __text:100002E6D call take_the_screenshot __text:100002E72 jmp loc_10000337B
__text:100007DC0 call _AudioServicesSetProperty __text:100007DC5 mov edi, [rbx] __text:100007DC7 call _AudioServicesPlaySystemSound
__text:100004155 mov [rsp+0E0h+var_E0], rax __text:100004159 mov edi, r12d __text:10000415C mov rsi, r15 __text:10000415F call doCapture __text:100004164 mov r14, rax __text:100004167 test r14, r14 __text:10000416A jz loc_100004236
__text:10000418F mov rdi, r14 ; img
__text:100004192 mov rsi, qword ptr [rbp+var_80]
__text:100004196 mov rdx, r15
__text:100004199 call writeImageToDisk
__text:10000419E mov rax, cs:qword_100012548
__text:1000041A5 add rax, 0FFFFFFFFFFFFFFFEh
__text:1000073D9 lea rax, cfstr_YouDontHavePer
; "You dont have permission to save files \
in the location where screen shots are stored."
__text:1000073E0 mov cs:qword_1000139F8, rax
__text:1000073E7 mov rax, cs:___stderrp_ptr
__text:1000073EE mov rdi, [rax] ; FILE *
__text:1000073F1 lea rsi, aScreencaptur_6 ; "screencapture: cannot write file to int"
__text:1000052EA call _CGRectIsEmpty
__text:1000052EF test al, al
__text:1000052F1 jz short loc_100005312
__text:1000052F3 mov edi, r12d
__text:1000052F6 call _CGDisplayCreateImage ; Returns an image containing the contents \
of the specified display
__text:1000052FB mov r15, rax
__text:1000052FE lea rbx, [rbp+var_C0]
__text:100005305 mov rdi, rbx
__text:100005308 mov esi, r12d
__text:10000530B call _CGDisplayBounds
__text:100005310 jmp short loc_100005343
__stubs:10000BDE4 _CGDisplayCreateImage proc near ; CODE XREF: doCapture+49
__stubs:10000BDE4 jmp cs:_CGDisplayCreateImage_ptr
__stubs:10000BDE4 _CGDisplayCreateImage endp
__text:00000546A public _CGDisplayCreateImage
__text:00000546A _CGDisplayCreateImage:
__text:00000546A jz short loc_5490
__text:00000546C sbb [rcx-75h], cl
__text:00000546F sbb [rax+39h], r9b
__text:00000546F
__text:000005473 db 0CEh, 75h, 1Bh, 49h, 8Bh
__text:000005478 dq 4820468B49202454h, \
88558B481675C239h, 181E998758B48h
__text:000005490
__text:000005490
__text:000005490 loc_5490: \
; CODE XREF: __text:_CGDisplayCreateImage
__text:000005490 add [rcx-75h], cl
__text:000005493 and [rcx-75h], r9b
__text:000005497 push rsp
__text:000005498 and al, 20h
__text:000005498
__text:00000549A dw 4866h
__text:00000549C db 0Fh
__text:00000549D
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
* frame #0: 0x00007fff6e726ef9 SkyLight`SLSHWCaptureDesktop + 5517
frame #1: 0x00007fff6e7294fa SkyLight`SLDisplayCreateImage + 34
frame #2: 0x1000052fb screencapture`___lldb_unnamed_symbol17$$screencapture + 78
frame #3: 0x100004164 screencapture`___lldb_unnamed_symbol12$$screencapture + 1092
frame #4: 0x100002e72 screencapture`___lldb_unnamed_symbol8$$screencapture + 2234
frame #5: 0x00007fff74579115 libdyld.dylib`start + 1
frame #6: 0x00007fff74579115 libdyld.dylib`start + 1
__text:0001FB4D8 public _SLDisplayCreateImage __text:0001FB4D8 _SLDisplayCreateImage proc near ... __text:0001FB4ED mov r8d, 441h __text:0001FB4F3 mov ecx, eax __text:0001FB4F5 call _SLSHWCaptureDesktop __text:0001FB4FA mov r14, rax
__text:0001F796C public _SLSHWCaptureDesktop __text:0001F796C _SLSHWCaptureDesktop proc near ... __text:0001F832E mov rcx, cs:_NDR_record_ptr __text:0001F8335 mov rcx, [rcx] __text:0001F8338 mov [rbp-0A8h], rcx __text:0001F833F movaps xmmword ptr [rbp+var_160], xmm1 __text:0001F8346 movups [rbp+var_A0], xmm1 __text:0001F834D movaps xmmword ptr [rbp+var_190], xmm0 __text:0001F8354 movups [rbp+var_90], xmm0 __text:0001F835B mov dword ptr [rbp+var_80], eax __text:0001F835E mov eax, [rbp+var_1A4] __text:0001F8364 mov dword ptr [rbp+var_80+4], eax __text:0001F8367 mov [rbp+msg.msgh_bits], 1513h __text:0001F8371 mov eax, [rbp+remote_port] __text:0001F8377 mov [rbp+msg.msgh_remote_port], eax __text:0001F837D call _mig_get_reply_port __text:0001F8382 mov [rbp+msg.msgh_local_port], eax __text:0001F8388 mov [rbp+msg.msgh_id], 732Ah __text:0001F8392 mov [rbp+msg.msgh_reserved], 0 __text:0001F839C cmp cs:_voucher_mach_msg_set_ptr, 0 __text:0001F83A4 jz short loc_1F83B8 __text:0001F83A6 lea rdi, [rbp+msg] __text:0001F83AD call _voucher_mach_msg_set __text:0001F83B2 mov eax, [rbp+msg.msgh_local_port] __text:0001F83B8 __text:0001F83B8 loc_1F83B8: __text:0001F83B8 sub rsp, 8 __text:0001F83BC mov esi, 3 ; option __text:0001F83C1 mov edx, 48h ; send_size __text:0001F83C6 mov ecx, 136 ; rcv_size __text:0001F83CB xor r9d, r9d ; timeout __text:0001F83CE lea rdi, [rbp+msg] ; msg __text:0001F83D5 mov r8d, eax ; rcv_name __text:0001F83D8 push 0 ; notify __text:0001F83DA call _mach_msg
struct req_msg* rq_msg = (struct req_msg*)buffer;
rq_msg->header.msgh_bits = 0x00001513;
rq_msg->header.msgh_size = 0;
rq_msg->header.msgh_remote_port = session_port;
rq_msg->header.msgh_local_port = mig_get_reply_port();
rq_msg->header.msgh_voucher_port = 0;
rq_msg->header.msgh_id = 0x732A;
// NDR Record value:
rq_msg->ndr.int_rep = 1;
// x, y, width, height of the rectangle to capture
rq_msg->x = 0.0;
rq_msg->y = 0.0;
rq_msg->width = 1024.0;
rq_msg->height = 768.0;
rq_msg->display_id = 0x047400b0;
rq_msg->param5 = 0x00000441; // ¯\_(ツ)_/¯
// set the voucher
voucher_mach_msg_set(&rq_msg->header);
// request the pixels
if(mach_msg(&rq_msg->header, 0x3, 0x48, 0x88,
rq_msg->header.msgh_local_port, 0, 0)
!= MACH_MSG_SUCCESS) {
printf("Error sending mach message\n");
exit(3);
}
__text:0001F796C public _SLSHWCaptureDesktop ... __text:0001F79A2 call _SLSMainConnectionID __text:0001F79A7 mov edi, eax __text:0001F79A9 __text:0001F79A9 loc_1F79A9: __text:0001F79A9 call _CGSGetConnectionPortById __text:0001F79AE mov [rbp+remote_port], eax __text:0001F79B4 test eax, eax
_SLSHWCaptureDesktop
> _SLSMainConnectionID
> _SLSNewConnection
> _SLSServerPort
> _CGSLookupServerRootPort
> _bootstrap_look_up2
(lldb) x/100wx $rdi
0x7ffeefbff640: 0x00131513 0x00000000 0x00002113 0x00000607
0x7ffeefbff650: 0x00001203 0x0000732a 0x00000000 0x00000001
(lldb) x/5i $rip
-> 0x7fff6e7263da: callq 0x7fff6e7868ca
; symbol stub for: mach_msg
0x7fff6e7263df: addq $0x10, %rsp
0x7fff6e7263e3: movl %eax, %r14d
0x7fff6e7263e6: leal -0x10000002(%r14), %eax
0x7fff6e7263ed: cmpl $0xe, %eax
$ lsmp -a
0x00002113 0x7591764b send ... WindowServer
$ ps -ef | grep WindowServer
88 201 /System/Library/PrivateFrameworks/ \
SkyLight.framework/Resources/WindowServer -daemon
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 3.1
* frame #0: 0x00007fff544c3287 SkyLight`_XHWCaptureDesktop
frame #1: 0x00007fff54638105 SkyLight`__connectionHandler_block_invoke + 87
frame #2: 0x00007fff5468aa57 SkyLight`CGXHandleMessage + 107
frame #3: 0x00007fff546373bf SkyLight`connectionHandler + 212
frame #4: 0x00007fff546caf21 SkyLight`post_port_data + 235
frame #5: 0x00007fff546cabfd SkyLight`run_one_server_pass + 949
frame #6: 0x00007fff546ca7d3 SkyLight`CGXRunOneServicesPass + 460
frame #7: 0x00007fff546cb2b9 SkyLight`SLXServer + 832
frame #8: 0x000000010afdddde WindowServer`_mh_execute_header + 3550
frame #9: 0x00007fff5a4ce115 libdyld.dylib`start + 1
# sudo frida-trace -a 'SkyLight!43287' WindowServer
Instrumenting functions...
sub_43287: Auto-generated handler at
"./__handlers__/SkyLight/sub_43287.js"
Started tracing 1 function. Press Ctrl+C to stop.
/* TID 0x307 */
6791 ms sub_43287()
(lldb)
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00007fff544c3287 SkyLight`_XHWCaptureDesktop
SkyLight`_XHWCaptureDesktop:
-> 0x7fff544c3287 <+0>: pushq %rbp
0x7fff544c3288 <+1>: movq %rsp, %rbp
0x7fff544c328b <+4>: pushq %r15
0x7fff544c328d <+6>: pushq %r14
Target 0: (WindowServer) stopped.
(lldb) x/10wx $rdi
0x7ffee4c12610: 0x00001112 0x00000048 0x000153ab 0x0001249b
0x7ffee4c12620: 0x00000000 0x0000732a 0x00000000 0x00000001
0x7ffee4c12630: 0x00000000 0x00000000
# lsmp -a
Process (4460) : screencapture
name ipc-object rights identifier type
--------- ---------- ---------- -------- -----
0x00000103 0x56e57599 send TASK SELF (4460) screencapture
...
0x00000603 0x56e56729 recv
+ send-once 0x000153ab (157) WindowServer
Process (157) : WindowServer name ipc-object rights identifier type --------- ---------- ---------- -------- ----- 0x000153ab 0x56e56729 send-once 0x00000603 (4460) screencapture
__text:10000236F ; void __cdecl -[macpsAppDelegate getscreenshot]
(struct macpsAppDelegate *self, SEL)
__text:10000236F __macpsAppDelegate_getscreenshot_ proc near
...
__text:10000250F lea rdx, cfstr_UsrSbinScreenc ; "/usr/sbin/screencapture"
__text:100002516 mov rdi, rbx
__text:100002519 call cs:msgRef_setLaunchPath
___objc_msgSend_fixup
__text:10000251F lea rsi, msgRef_arrayWithObjects
___objc_msgSend_fixup
__text:100002526 lea rdx, stru_100034A88 ; "-x"
__text:10000252D lea rcx, cfstr_T ; "-T"
__text:100002534 lea r8, cfstr_20 ; "20
#include <CoreFoundation/CFURL.h>
#include <ImageIO/CGImageDestination.h>
#include <CoreGraphics/CGDirectDisplay.h>
void doCGCapture() {
CGDirectDisplayID displays[256];
uint32_t dispCount = 0;
// get a list of all displays
if(CGGetActiveDisplayList(256, displays, &dispCount)) {
printf("Error getting display list\n");
return;
}
// iterate screens and take the screenshots
for(int i = 0; i < dispCount; i++) {
CGDirectDisplayID dispId = displays[i];
// get the raw pixels
CGImageRef img = CGDisplayCreateImage(dispId);
char path_str[1024];
snprintf(path_str, 1023, "./image%d.png", i);
// output file
CFURLRef path =
CFURLCreateWithFileSystemPath(NULL,
__CFStringMakeConstantString(path_str),
kCFURLPOSIXPathStyle, false);
// file/format to save pixels to
CGImageDestinationRef destination =
CGImageDestinationCreateWithURL(
path, CFSTR("public.png"), 1, NULL); //[4]
// add our captured pixels
CGImageDestinationAddImage(destination, img, nil);
// generate the image
if (!CGImageDestinationFinalize(destination)) {
printf("Failed to finalize\n");
}
}
}
(deny mach-lookup
(global-name "com.apple.windowserver.active"))
(deny mach-msg
(mach-msg-id 0x732a))
0 - Mach Overview
1 - Frida
3 - Lockheed Martin F-35 Lightning II
4 - System-Declared Uniform Type Identifiers
5 - New Mac Malware Takes Screenshots And Uploads Them Without Permission
6 - ScreenShot_DetectorAppDelegate.m
7 - Mac Privacy: Sandboxed Mac apps can record your screen at any time without you knowing
8 - @patrickwardle: …but we can't say we weren't ‘warned' From 2011