Showing posts with label Mac. Show all posts
Showing posts with label Mac. Show all posts

Wednesday, March 24, 2021

Differences of Mac and Linux Assembly Language

This example demo the differences of Assembly Language in Mac and Linux for x86_64 architecture. For arm64 assembly language differences, see these 2 codes in github. https://github.com/below/HelloSilicon and https://github.com/Apress/programming-with-64-bit-ARM-assembly-language

The assembly code has read and write functions. The differences of Linux and macOS are using the %ifdef MACHO64 which is the code for macOS %else is for Linux. For example the system call numbers are different and macho64 cannot use absolute addressing.
01_05-solution1.asm   Select all
; solution - answer to Chapter 1 challenge ; Read decimal input, add 10, generate output section .data prompt db "How old are you? ",0 result db "In 10 years, you will be ",0 newline db 10 ; newline, \n ten dq 10 ; used for multiplication size equ 4 ; buffer size azero equ 0x30 ; ASCII zero, '0' anine equ 0x39 ; ASCII nine, '9' nullchar equ 0x0 ; null terminator, \0 STDIN equ 0 ; standard input device STDOUT equ 1 ; standard output device %ifdef MACHO64 SYS_read equ 0x2000003 ; system call to read input macOS SYS_write equ 0x2000004 ; system call to write message macOS SYS_exit equ 0x2000001 ; system call to terminate program macOS %else SYS_read equ 0 ; system call to read input SYS_write equ 1 ; system call to write message SYS_exit equ 60 ; system call to terminate program %endif EXIT_OK equ 0 ; OK exit status TENS dq 10000 ; tens table dq 1000 dq 100 dq 10 dq 1 ; uninitialized data section .bss input_buf resb size ; age input buffer age resq 1 ; binary age value output_buf resb size ; modified age string ; code section .text global _start _start: ; output the prompt mov rsi, prompt ; prompt string output call print_string ; read input mov rbx, input_buf ; age string storage call input ; translate decimal string to binary mov rsi, input_buf ; where string value is stored call decimal2binary cmp al, 0 ; check for bogus input jz start_exit ; bail if so add rax, 10 ; add 10 to the value %ifdef MACHO64 mov [rel age], rax ; store result %else mov [age], rax ; store result %endif ; output the final prompt mov rsi, result ; First part of the string call print_string ; convert the value in 'age' to a string %ifdef MACHO64 mov rbx, [rel age] ; value %else mov rbx, [age] ; value %endif mov rsi, output_buf ; modified string call binary2decimal ; output the age-value string mov rsi, output_buf call print_value ; use this function to strip leading ; zeros ; exit program start_exit: mov rax, SYS_exit ; system exit call mov rdi, EXIT_OK syscall ; end of _start ; functions ;--------; ; output a null terminated string in rsi print_string: cmp byte [rsi], nullchar ; end-of-string test je print_string_exit ; bail on null char mov rdx, 1 ; number of characters to write mov rdi, STDOUT ; to standard output mov rax, SYS_write ; Write characters(s) syscall inc rsi ; next character jmp print_string ; keep looping print_string_exit: ret ;--------; ; grab standard input in the buffer in rbx input: mov r12, 1 ; buffer position read_char: mov rsi, rbx ; input char storage mov rdx, 1 ; character count mov rdi, STDIN ; from standard input mov rax, SYS_read ; read into rsi (rbx) syscall cmp byte [rbx], 10 ; is character read newline? je input_exit ; finish, don't store newline inc rbx ; next byte in the buffer inc r12 ; up the character count cmp r12, size ; check buffer size jl read_char ; keep looping if room ; otherwise, fall through: input_exit: mov byte [rbx], 0 ; cap the string ret ;--------; ; translate string input at rsi into binary value in rax ; if garbage input, returned value is zero decimal2binary: mov rax, 0 ; initial value d2b0: mov rbx, 0 ; initialize bax mov bl, byte [rsi] ; character, digit ; filter out non-digit values cmp bl, azero jl d2b_exit ; exit on character < '0' cmp bl, anine jg d2b_exit ; exit on character > '9' sub bl, azero ; convert from ASCII to binary %ifdef MACHO64 mul qword [rel ten] ; multiply rax by 10 %else mul qword [ten] ; multiply rax by 10 %endif add rax, rbx ; add new value inc rsi ; next char cmp byte [rsi], nullchar ; end of string? jnz d2b0 ; if not, keep looping d2b_exit: ret ;--------; ; generate a string at rsi representing the value in rbx binary2decimal: mov rdi, TENS ; reference comparision table ; values here are subtracted from ; rbx to calculate base 10 digits b2d0: xor al, al ; zero out al; al stores the character mov rcx, [rdi] ; get power of ten b2d1: or al, al ; clear carry bit (for jb) sub rbx, rcx ; subtract power of ten jb b2d2 ; if <0, the count in al is the value inc al ; decimal value++ jmp b2d1 ; keep subtracting b2d2: add al, azero ; make al ASCII add rbx, rcx ; recover from last subtraction mov byte [rsi], al ; add character to the string inc rsi ; next string position add rdi, 8 ; next value in TENS table cmp rcx, 1 ; end of table? jnz b2d0 ; loop again if not mov byte [rsi], nullchar ; terminate string ret ;--------; ; output a null-terminated string in rsi ; strip any leading zero characters print_value: cmp byte [rsi], nullchar ; always check for null char je print_value_exit ; and exit; string empty cmp byte [rsi], azero ; ASCII zero jne pv1 ; if the char isnt zero, continue inc rsi ; otherwise, check next character jmp print_value ; keep looping pv1: ; process the remaining non-zero digits cmp byte [rsi], nullchar ; null char terminator je print_value_exit ; if true, exit mov rdx, 1 ; chars to write mov rdi, STDOUT ; standard output mov rax, SYS_write ; write characters syscall inc rsi ; next char jmp pv1 ; loop until null char print_value_exit: mov rsi, newline ; newline defined as \n mov rdx, 1 ; write 1 char mov rax, SYS_write ; write character mov rdi, STDOUT ; to standard output syscall ret ; end


makefile for Linux
makefile   Select all
#makefile for Linux filename_prefix := 01_05- src_files := $(wildcard *.asm) obj_files := $(src_files:.asm=.o) prog_files := $(subst $(filename_prefix), ,$(basename $(src_files))) all: $(prog_files) $(prog_files): % : $(filename_prefix)%.o ld -o $@ $< -arch x86_64 $(filter %.o,$(obj_files)): %.o : %.asm nasm -g -f elf64 $< -o $@ .PHONY: clean clean: rm -f $(obj_files) $(prog_files)


makefile for macOS
makefile    Select all
#makefile for macOS filename_prefix := 01_05- src_files := $(wildcard *.asm) obj_files := $(src_files:.asm=.o) prog_files := $(subst $(filename_prefix), ,$(basename $(src_files))) all: $(prog_files) $(prog_files): % : $(filename_prefix)%.o ld -no_pie -macosx_version_min 11.0.0 -o $@ $< -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch x86_64 codesign --entitlement entitlements --force -s - $@ $(filter %.o,$(obj_files)): %.o : %.asm nasm -g -f macho64 -dMACHO64 $< -o $@ .PHONY: clean clean: rm -f $(obj_files) $(prog_files)


In order to debug in macOS, codesign entitlement file is needed.
entitlements   Select all
<?xml version="1.0" encoding="UTF-8"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.get-task-allow</key> <true/> </dict> </plist>


For linux, it is required to install these packages "sudo apt install build-essentials nasm gdb lldb"

For macOS, it is required to install Xcode and Command Line Tools and Homebrew package "brew install nasm"
It is possible to build, run and debug x86_64 program on M1 Macs, if Rosetta is installed.


Wednesday, February 24, 2010

Wednesday, September 17, 2008

Recent apps on your dock for Mac

http://www.tuaw.com/2008/09/16/terminal-tips-add-recent-applications-as-a-stack-on-dock/

Type this in Mac Terminal

defaults write com.apple.dock persistent-others -array-add '{ "tile-data" = { "list-type" = 1; }; "tile-type" = "recents-tile"; }'
killall Dock

Tuesday, February 5, 2008

I'm a new soul I can do this strange world hoping I could learn a bit about how to give and take

I'm a new soul I can do this strange world hoping I could learn a bit about how to give and take.
But since I came here felt the joy and the fear finding myself making every possible mistake

la-la-la-la-la-la-la-la...

I'm a young soul in this very strange world hoping I could learn a bit about what is true and fake. 
But why don't please trying to comunnicate finding trust and love is not always easy to make.

la-la-la-la-la-la-la-la...

This is a happy end cause' you don't understand everything you have done wise everything so wrong

this is a happy end come and give me your hand I'll take your far away.

[Refrain]:
I'm a new soul I can do this strange world hoping I could learn a bit about how to give and take but since I came here fellt the joy and the fear finding myself making every possible mistake

la-la-la-la-la-la-la-la...

la-la-la-la-la-la-la-la-la-la....

Monday, January 28, 2008

Decrypt iPhone filesystem Firmware using Mac OS or Linux

If you use Mac OS and want to extract the iPhone Firmware in your computer, you can follow the instructions below. If you use Windows PC, please refer to another post here

(1) get the vfdecrypt binary for Mac (Universal Binary)


If you use linux, you can get the source code from here and compile with
gcc vfdecrypt.c -o vfdecrypt -lcrypto


For this linux version, line 357 should be changed to
  while((c = getopt(argc, argv, "hvi:o:p:k:")) != -1) {


(2) Run the shell script below to download the firmware and get the decrypted dmg


#!/bin/bash
key100=28c909fc6d322fa18940f03279d70880e59a4507998347c70d5b8ca7ef090ecccc15e82d
key101=7d5962d0b582ec2557c2cade50de90f4353a1c1de07b74212513fef9cc71fb890574bfe5
key102=7d5962d0b582ec2557c2cade50de90f4353a1c1de07b74212513fef9cc71fb890574bfe5
key111=f45de7637a62b200950e550f4144696d7ff3dc5f0b19c8efdf194c88f3bc2fa808fea3b3
key112=70e11d7209602ada5b15fbecc1709ad4910d0ad010bb9a9125b78f9f50e25f3e05c595e2
key113=11070c11d93b9be5069b643204451ed95aad37df7b332d10e48fd3d23c62fca517055816
key114=d0a0c0977bd4b6350b256d6650ec9eca419b6f961f593e74b7e5b93e010b698ca6cca1fe
key120=ea14f3ec624c7fdbd52e108aa92d13b16f6b0b940c841f7bbc7792099dae45da928d13e7

ipswurl100=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-3538.20070629.B7vXa/iPhone1,1_1.0_1A543a_Restore.ipsw
ipswurl101=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-3614.20070731.Nt6Y7/iPhone1,1_1.0.1_1C25_Restore.ipsw
ipswurl102=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-3823.20070821.vormd/iPhone1,1_1.0.2_1C28_Restore.ipsw
ipswurl111=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-3883.20070927.In76t/iPhone1,1_1.1.1_3A109a_Restore.ipsw
ipswurl112=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-4037.20071107.5Bghn/iPhone1,1_1.1.2_3B48b_Restore.ipsw
ipswurl113=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-4061.20080115.4Fvn7/iPhone1,1_1.1.3_4A93_Restore.ipsw
ipswurl114=http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-4313.20080226.Sw39i/iPhone1,1_1.1.4_4A102_Restore.ipsw
ipswurl120=http://appldnld.apple.com.edgesuite.net/

ipswname100=iPhone1,1_1.0_1A543a_Restore.ipsw
ipswname101=iPhone1,1_1.0.1_1C25_Restore.ipsw
ipswname102=iPhone1,1_1.0.2_1C28_Restore.ipsw
ipswname111=iPhone1,1_1.1.1_3A109a_Restore.ipsw
ipswname112=iPhone1,1_1.1.2_3B48b_Restore.ipsw
ipswname113=iPhone1,1_1.1.3_4A93_Restore.ipsw
ipswname114=iPhone1,1_1.1.4_4A102_Restore.ipsw
ipswname120=iPhone1,1_2.0_5A225c_Restore.ipsw

dmgname100=694-5262-39.dmg
dmgname101=694-5281-6.dmg
dmgname102=694-5298-5.dmg
dmgname111=022-3602-17.dmg
dmgname112=022-3725-1.dmg
dmgname113=022-3743-100.dmg
dmgname114=022-3894-4.dmg
dmgname120=018-3473-4.dmg

decrypted100=decrypted100.dmg
decrypted101=decrypted101.dmg
decrypted102=decrypted102.dmg
decrypted111=decrypted111.dmg
decrypted112=decrypted112.dmg
decrypted113=decrypted113.dmg
decrypted114=decrypted114.dmg
decrypted120=decrypted120.dmg


# default is to get the latest firmware
# you can pass multiple arguments
# in command line to get more than one
if [ $# -lt 1 ]
then
getipsw=120
else
getipsw=$@
fi

for ipsw_ver in $getipsw
do
ipswname=$(eval "echo \$$(echo ipswname${ipsw_ver})")
ipswurl=$(eval "echo \$$(echo ipswurl${ipsw_ver})")
ipswpath=`pwd`/$ipswname
decryptedname=$(eval "echo \$$(echo decrypted${ipsw_ver})")
dmgname=$(eval "echo \$$(echo dmgname${ipsw_ver})")
key=$(eval "echo \$$(echo key${ipsw_ver})")
decryptpath=`pwd`/$decryptedname
if [ -f "$ipswpath" ]
then
echo Firmware $ipsw_ver "$ipswname" found
else
echo Downloading firmware $ipsw_ver $ipswname
curl "$ipswurl" > $ipswpath
fi

if [ -f "$decryptpath" ]
then
echo Firmware $ipsw_ver "$decryptedname" found
else
if [ -f "$ipswpath" ]
then
echo Extracting firmware $ipsw_ver $dmgname
unzip -o $ipswname $dmgname -d .
fi
if [ -f "$dmgname" ]
then
echo Decrypting firmware $ipsw_ver $ipswname
./vfdecrypt -i $dmgname -o $decryptedname -k $key
fi
fi
done
echo Jobs Completed!!!



(3) Mount the decrypted dmg in Mac OS by double click the filename

(4) For Firmware key for 1.0.1 you can run
strings 009-7662-6.dmg | egrep "^[0-9a-fA-F]{72}$"
and This is how you find the key.

(5) This is where you can find the Firmware download link from Apple
http://itunes.com/version


If you find this info useful, please consider to $1 by clicking the Donate button.