- Timestamp:
- 05/09/06 05:56:05 (19 years ago)
- Location:
- trunk/Cocoa/F-Script Anywhere/Source
- Files:
-
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cocoa/F-Script Anywhere/Source/English.lproj/FSAInterpreterPanel.nib/data.dependency
r7 r217 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">3 <plist version=" 0.9">2 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 <plist version="1.0"> 4 4 <dict> 5 5 <key>IBPaletteDependency</key> -
trunk/Cocoa/F-Script Anywhere/Source/English.lproj/FSAInterpreterPanel.nib/info.nib
r7 r217 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">3 <plist version=" 0.9">2 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 <plist version="1.0"> 4 4 <dict> 5 5 <key>IBDocumentLocation</key> 6 <string> 99 33 356 240 0 0 1600 1178</string>6 <string>74 99 356 240 0 0 1280 1002 </string> 7 7 <key>IBFramework Version</key> 8 <string> 263.2</string>8 <string>443.0</string> 9 9 <key>IBOpenObjects</key> 10 10 <array> … … 12 12 </array> 13 13 <key>IBSystem Version</key> 14 <string> 5S66</string>14 <string>8H14</string> 15 15 </dict> 16 16 </plist> -
trunk/Cocoa/F-Script Anywhere/Source/English.lproj/MainMenu.nib/info.nib
r153 r217 4 4 <dict> 5 5 <key>IBDocumentLocation</key> 6 <string>113 10 356 240 0 0 1280 832 </string>6 <string>113 87 356 240 0 0 1280 1002 </string> 7 7 <key>IBEditorPositions</key> 8 8 <dict> 9 9 <key>29</key> 10 <string>53 175 213 44 0 0 1280 832 </string>10 <string>53 213 232 44 0 0 1280 1002 </string> 11 11 </dict> 12 12 <key>IBFramework Version</key> 13 <string> 349.0</string>13 <string>443.0</string> 14 14 <key>IBOpenObjects</key> 15 15 <array> 16 <integer>29</integer> 16 17 <integer>195</integer> 17 <integer>29</integer>18 18 </array> 19 19 <key>IBSystem Version</key> 20 <string> 7D24</string>20 <string>8H14</string> 21 21 </dict> 22 22 </plist> -
trunk/Cocoa/F-Script Anywhere/Source/FSAApp.mm
r153 r217 90 90 if ((err = AEGetAttributePtr(theAE, keyEventIDAttr, typeType, &actualType, &eventID, sizeof(OSType), &actualSize)) != noErr) 91 91 return; 92 92 93 #if 0 93 94 if (eventID == kSCLoadResult) { 94 95 OSStatus … … 98 99 printf("patch bundle %s loaded with error status %d\n", bundleID, error); 99 100 } 101 #endif 100 102 101 103 … … 234 236 if (err == noErr) 235 237 err = patchController->PatchProcess(&psn); 236 238 237 239 if (err != noErr) 238 240 [self installationError: err inAppWithPID: pid]; -
trunk/Cocoa/F-Script Anywhere/Source/FSAnywhere.h
r153 r217 10 10 #define FSA_VERSION "1.2b1" 11 11 #define FSA_FSCRIPT_MIN_VERSION 0x1252001 /* 1.2.5d1 */ 12 # defineFSA_DEBUG12 #undef FSA_DEBUG 13 13 14 14 #ifdef FSA_DEBUG -
trunk/Cocoa/F-Script Anywhere/Source/FSAnywhere.m
r153 r217 11 11 12 12 NSString * FSA_FScriptURL = @"http://www.fscript.org/"; 13 NSString * FSA_FScriptMinimumVersion = @"1. 2.5";13 NSString * FSA_FScriptMinimumVersion = @"1.3.0"; -
trunk/Cocoa/F-Script Anywhere/Source/SCPatch/SCPatchClient/SCPatchClient.cpp
r153 r217 37 37 38 38 if(client->Initialize(client->mClientBundleID, client->mControllerBundleID, getpid()) != noErr) 39 return err_threadEntry_i nit_failed;39 return err_threadEntry_image_not_found; 40 40 41 41 // Create a port to receive messages from our patch controller 42 42 if((err = client->StartListening(client->mClientBundleID, true, true)) != noErr) 43 return err_threadEntry_i nit_failed;43 return err_threadEntry_image_not_found; 44 44 45 45 if((err = GetCurrentProcess(&psn)) != noErr || … … 48 48 CFStringGetCStringPtr(client->mClientBundleID, kCFStringEncodingMacRoman), 49 49 sizeof(ProcessSerialNumber), &psn)) != noErr) 50 return err_threadEntry_i nit_failed;50 return err_threadEntry_image_not_found; 51 51 52 52 return noErr; -
trunk/Cocoa/F-Script Anywhere/Source/SCPatch/SCPatchController/SCPatchController.cpp
r153 r217 17 17 //------------------------------------------------------------------------------------------------------------- 18 18 OSErr SCOSErrFrom_mac_err(mach_error_t error) { 19 return (error & err_mac) ? (err & ^err_mac) : noErr;19 return (error & err_mac) ? (err_mac) : noErr; 20 20 } 21 21 … … 323 323 if(err == noErr) 324 324 error = InjectPatches(psn, params); 325 326 325 free(params); 327 326 } 328 327 CFRelease(str); 329 328 } 329 330 330 if (error != err_none) return error; 331 331 else return mac_err(err); … … 436 436 // Find the loader 437 437 CFURLRef loaderURL = NULL; 438 #if defined(__ppc__) || defined(__ppc64__) 438 439 if(!err) 439 440 if((loaderURL = CFBundleCopyResourceURL(mBundle, CFSTR("SCPatchLoader"), CFSTR("bundle"), NULL)) == NULL) 440 441 err = err_couldnt_find_injection_bundle; 442 #else 443 if(!err) 444 if((loaderURL = CFBundleCopyResourceURL(mBundle, CFSTR("SCPatchLoader-intel"), CFSTR("bundle"), NULL)) == NULL) 445 err = err_couldnt_find_injection_bundle; 446 #endif 441 447 442 448 #if 0 … … 483 489 fprintf(stderr, "Patcher got error %d\n", err); 484 490 } 485 491 486 492 // Clean up. 487 493 if(loaderURL) -
trunk/Cocoa/F-Script Anywhere/Source/SCPatch/SCPatchController/SCPatchLoader.c
r153 r217 199 199 200 200 //------------------------------------------------------------------------------------------------------------- 201 mach_error_t INJECT_ENTRY( ptrdiff_t codeOffset, void *paramBlock, size_t paramSize )201 mach_error_t INJECT_ENTRY( ptrdiff_t codeOffset, void *paramBlock, size_t paramSize, char *dummy_pthread_struct ) 202 202 { 203 203 pthread_t thread; … … 205 205 struct sched_param sched; 206 206 int policy; 207 207 #if defined (__i386__) 208 // On intel, per-pthread data is a zone of data that must be allocated. 209 // if not, all function trying to access per-pthread data (all mig functions for instance) 210 // will crash. 211 extern void __pthread_set_self(char*); 212 __pthread_set_self(dummy_pthread_struct); 213 #endif 208 214 // We need to fix up function addresses in gcc code, but not for code generated by CW. 209 #ifdef __MWERKS__ 215 // It turns out that this is not needed for gcc 4.0 216 //#ifdef __MWERKS__ 210 217 codeOffset = 0; 211 #endif218 //#endif 212 219 // Stash the code offset where we can get at it later. 213 220 ((SCPatchLoaderParams *)paramBlock)->codeOffset = codeOffset; -
trunk/Cocoa/F-Script Anywhere/Source/bytesex.c
r7 r217 1 1 /* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 2 * Copyright (c) 2004, Apple Computer, Inc. All rights reserved. 5 3 * 6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.1 (the "License"). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 13 * its contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 13 15 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 16 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 23 27 */ 24 28 /* byte_sex.c */ 25 29 #include <string.h> 30 #include "stuff/target_arch.h" 26 31 #include <mach-o/fat.h> 27 32 #include <mach-o/loader.h> 28 #import <mach/m68k/thread_status.h> 29 #import <mach/ppc/thread_status.h> 30 #import <mach/m88k/thread_status.h> 31 #import <mach/i860/thread_status.h> 32 #import <mach/i386/thread_status.h> 33 #import <mach/hppa/thread_status.h> 34 #import <mach/sparc/thread_status.h> 33 #include <mach/m68k/thread_status.h> 34 #undef MACHINE_THREAD_STATE /* need to undef these to avoid warnings */ 35 #undef MACHINE_THREAD_STATE_COUNT 36 #include <mach/ppc/thread_status.h> 37 #undef MACHINE_THREAD_STATE /* need to undef these to avoid warnings */ 38 #undef MACHINE_THREAD_STATE_COUNT 39 #include <mach/m88k/thread_status.h> 40 #include <mach/i860/thread_status.h> 41 #include <mach/i386/thread_status.h> 42 #include <mach/hppa/thread_status.h> 43 #include <mach/sparc/thread_status.h> 35 44 #include <mach-o/nlist.h> 36 45 #include <mach-o/reloc.h> … … 38 47 #include "stuff/bool.h" 39 48 #include "stuff/bytesex.h" 49 50 __private_extern__ 51 long long 52 SWAP_LONG_LONG( 53 long long ll) 54 { 55 union { 56 char c[8]; 57 long long ll; 58 } in, out; 59 in.ll = ll; 60 out.c[0] = in.c[7]; 61 out.c[1] = in.c[6]; 62 out.c[2] = in.c[5]; 63 out.c[3] = in.c[4]; 64 out.c[4] = in.c[3]; 65 out.c[5] = in.c[2]; 66 out.c[6] = in.c[1]; 67 out.c[7] = in.c[0]; 68 return(out.ll); 69 } 40 70 41 71 __private_extern__ … … 150 180 __private_extern__ 151 181 void 182 swap_mach_header_64( 183 struct mach_header_64 *mh, 184 enum byte_sex target_byte_sex) 185 { 186 #ifdef __MWERKS__ 187 enum byte_sex dummy; 188 dummy = target_byte_sex; 189 #endif 190 mh->magic = SWAP_LONG(mh->magic); 191 mh->cputype = SWAP_LONG(mh->cputype); 192 mh->cpusubtype = SWAP_LONG(mh->cpusubtype); 193 mh->filetype = SWAP_LONG(mh->filetype); 194 mh->ncmds = SWAP_LONG(mh->ncmds); 195 mh->sizeofcmds = SWAP_LONG(mh->sizeofcmds); 196 mh->flags = SWAP_LONG(mh->flags); 197 mh->reserved = SWAP_LONG(mh->reserved); 198 } 199 200 __private_extern__ 201 void 152 202 swap_load_command( 153 203 struct load_command *lc, … … 187 237 __private_extern__ 188 238 void 239 swap_segment_command_64( 240 struct segment_command_64 *sg, 241 enum byte_sex target_byte_sex) 242 { 243 #ifdef __MWERKS__ 244 enum byte_sex dummy; 245 dummy = target_byte_sex; 246 #endif 247 /* segname[16] */ 248 sg->cmd = SWAP_LONG(sg->cmd); 249 sg->cmdsize = SWAP_LONG(sg->cmdsize); 250 sg->vmaddr = SWAP_LONG_LONG(sg->vmaddr); 251 sg->vmsize = SWAP_LONG_LONG(sg->vmsize); 252 sg->fileoff = SWAP_LONG_LONG(sg->fileoff); 253 sg->filesize = SWAP_LONG_LONG(sg->filesize); 254 sg->maxprot = SWAP_LONG(sg->maxprot); 255 sg->initprot = SWAP_LONG(sg->initprot); 256 sg->nsects = SWAP_LONG(sg->nsects); 257 sg->flags = SWAP_LONG(sg->flags); 258 } 259 260 __private_extern__ 261 void 189 262 swap_section( 190 263 struct section *s, … … 203 276 s[i].addr = SWAP_LONG(s[i].addr); 204 277 s[i].size = SWAP_LONG(s[i].size); 278 s[i].offset = SWAP_LONG(s[i].offset); 279 s[i].align = SWAP_LONG(s[i].align); 280 s[i].reloff = SWAP_LONG(s[i].reloff); 281 s[i].nreloc = SWAP_LONG(s[i].nreloc); 282 s[i].flags = SWAP_LONG(s[i].flags); 283 s[i].reserved1 = SWAP_LONG(s[i].reserved1); 284 s[i].reserved2 = SWAP_LONG(s[i].reserved2); 285 } 286 } 287 288 __private_extern__ 289 void 290 swap_section_64( 291 struct section_64 *s, 292 unsigned long nsects, 293 enum byte_sex target_byte_sex) 294 { 295 unsigned long i; 296 #ifdef __MWERKS__ 297 enum byte_sex dummy; 298 dummy = target_byte_sex; 299 #endif 300 301 for(i = 0; i < nsects; i++){ 302 /* sectname[16] */ 303 /* segname[16] */ 304 s[i].addr = SWAP_LONG_LONG(s[i].addr); 305 s[i].size = SWAP_LONG_LONG(s[i].size); 205 306 s[i].offset = SWAP_LONG(s[i].offset); 206 307 s[i].align = SWAP_LONG(s[i].align); … … 542 643 cpu->ctr = SWAP_LONG(cpu->ctr); 543 644 cpu->mq = SWAP_LONG(cpu->mq); 544 cpu->pad = SWAP_LONG(cpu->pad); 645 cpu->vrsave = SWAP_LONG(cpu->vrsave); 646 } 647 648 __private_extern__ 649 void 650 swap_ppc_thread_state64_t( 651 ppc_thread_state64_t *cpu, 652 enum byte_sex target_byte_sex) 653 { 654 cpu->srr0 = SWAP_LONG_LONG(cpu->srr0); 655 cpu->srr1 = SWAP_LONG_LONG(cpu->srr1); 656 cpu->r0 = SWAP_LONG_LONG(cpu->r0); 657 cpu->r1 = SWAP_LONG_LONG(cpu->r1); 658 cpu->r2 = SWAP_LONG_LONG(cpu->r2); 659 cpu->r3 = SWAP_LONG_LONG(cpu->r3); 660 cpu->r4 = SWAP_LONG_LONG(cpu->r4); 661 cpu->r5 = SWAP_LONG_LONG(cpu->r5); 662 cpu->r6 = SWAP_LONG_LONG(cpu->r6); 663 cpu->r7 = SWAP_LONG_LONG(cpu->r7); 664 cpu->r8 = SWAP_LONG_LONG(cpu->r8); 665 cpu->r9 = SWAP_LONG_LONG(cpu->r9); 666 cpu->r10 = SWAP_LONG_LONG(cpu->r10); 667 cpu->r11 = SWAP_LONG_LONG(cpu->r11); 668 cpu->r12 = SWAP_LONG_LONG(cpu->r12); 669 cpu->r13 = SWAP_LONG_LONG(cpu->r13); 670 cpu->r14 = SWAP_LONG_LONG(cpu->r14); 671 cpu->r15 = SWAP_LONG_LONG(cpu->r15); 672 cpu->r16 = SWAP_LONG_LONG(cpu->r16); 673 cpu->r17 = SWAP_LONG_LONG(cpu->r17); 674 cpu->r18 = SWAP_LONG_LONG(cpu->r18); 675 cpu->r19 = SWAP_LONG_LONG(cpu->r19); 676 cpu->r20 = SWAP_LONG_LONG(cpu->r20); 677 cpu->r21 = SWAP_LONG_LONG(cpu->r21); 678 cpu->r22 = SWAP_LONG_LONG(cpu->r22); 679 cpu->r23 = SWAP_LONG_LONG(cpu->r23); 680 cpu->r24 = SWAP_LONG_LONG(cpu->r24); 681 cpu->r25 = SWAP_LONG_LONG(cpu->r25); 682 cpu->r26 = SWAP_LONG_LONG(cpu->r26); 683 cpu->r27 = SWAP_LONG_LONG(cpu->r27); 684 cpu->r28 = SWAP_LONG_LONG(cpu->r28); 685 cpu->r29 = SWAP_LONG_LONG(cpu->r29); 686 cpu->r30 = SWAP_LONG_LONG(cpu->r30); 687 cpu->r31 = SWAP_LONG_LONG(cpu->r31); 688 cpu->cr = SWAP_LONG(cpu->cr); 689 cpu->xer = SWAP_LONG_LONG(cpu->xer); 690 cpu->lr = SWAP_LONG_LONG(cpu->lr); 691 cpu->ctr = SWAP_LONG_LONG(cpu->ctr); 692 cpu->vrsave = SWAP_LONG(cpu->vrsave); 545 693 } 546 694 … … 1690 1838 __private_extern__ 1691 1839 void 1840 swap_routines_command_64( 1841 struct routines_command_64 *r_cmd, 1842 enum byte_sex target_byte_sex) 1843 { 1844 #ifdef __MWERKS__ 1845 enum byte_sex dummy; 1846 dummy = target_byte_sex; 1847 #endif 1848 r_cmd->cmd = SWAP_LONG(r_cmd->cmd); 1849 r_cmd->cmdsize = SWAP_LONG(r_cmd->cmdsize); 1850 r_cmd->init_address = SWAP_LONG_LONG(r_cmd->init_address); 1851 r_cmd->init_module = SWAP_LONG_LONG(r_cmd->init_module); 1852 r_cmd->reserved1 = SWAP_LONG_LONG(r_cmd->reserved1); 1853 r_cmd->reserved2 = SWAP_LONG_LONG(r_cmd->reserved2); 1854 r_cmd->reserved3 = SWAP_LONG_LONG(r_cmd->reserved3); 1855 r_cmd->reserved4 = SWAP_LONG_LONG(r_cmd->reserved4); 1856 r_cmd->reserved5 = SWAP_LONG_LONG(r_cmd->reserved5); 1857 r_cmd->reserved6 = SWAP_LONG_LONG(r_cmd->reserved6); 1858 } 1859 1860 __private_extern__ 1861 void 1692 1862 swap_twolevel_hints_command( 1693 1863 struct twolevel_hints_command *hints_cmd, … … 1777 1947 symbols[i].n_desc = SWAP_SHORT(symbols[i].n_desc); 1778 1948 symbols[i].n_value = SWAP_LONG(symbols[i].n_value); 1949 } 1950 } 1951 1952 __private_extern__ 1953 void 1954 swap_nlist_64( 1955 struct nlist_64 *symbols, 1956 unsigned long nsymbols, 1957 enum byte_sex target_byte_sex) 1958 { 1959 unsigned long i; 1960 #ifdef __MWERKS__ 1961 enum byte_sex dummy; 1962 dummy = target_byte_sex; 1963 #endif 1964 1965 for(i = 0; i < nsymbols; i++){ 1966 symbols[i].n_un.n_strx = SWAP_LONG(symbols[i].n_un.n_strx); 1967 /* n_type */ 1968 /* n_sect */ 1969 symbols[i].n_desc = SWAP_SHORT(symbols[i].n_desc); 1970 symbols[i].n_value = SWAP_LONG_LONG(symbols[i].n_value); 1779 1971 } 1780 1972 } … … 1963 2155 __private_extern__ 1964 2156 void 2157 swap_dylib_module_64( 2158 struct dylib_module_64 *mods, 2159 unsigned long nmods, 2160 enum byte_sex target_byte_sex) 2161 { 2162 unsigned long i; 2163 #ifdef __MWERKS__ 2164 enum byte_sex dummy; 2165 dummy = target_byte_sex; 2166 #endif 2167 2168 for(i = 0; i < nmods; i++){ 2169 mods[i].module_name = SWAP_LONG(mods[i].module_name); 2170 mods[i].iextdefsym = SWAP_LONG(mods[i].iextdefsym); 2171 mods[i].nextdefsym = SWAP_LONG(mods[i].nextdefsym); 2172 mods[i].irefsym = SWAP_LONG(mods[i].irefsym); 2173 mods[i].nrefsym = SWAP_LONG(mods[i].nrefsym); 2174 mods[i].ilocalsym = SWAP_LONG(mods[i].ilocalsym); 2175 mods[i].nlocalsym = SWAP_LONG(mods[i].nlocalsym); 2176 mods[i].iextrel = SWAP_LONG(mods[i].iextrel); 2177 mods[i].nextrel = SWAP_LONG(mods[i].nextrel); 2178 mods[i].iinit_iterm = SWAP_LONG(mods[i].iinit_iterm); 2179 mods[i].ninit_nterm = SWAP_LONG(mods[i].ninit_nterm); 2180 mods[i].objc_module_info_addr = 2181 SWAP_LONG_LONG(mods[i].objc_module_info_addr); 2182 mods[i].objc_module_info_size = 2183 SWAP_LONG_LONG(mods[i].objc_module_info_size); 2184 } 2185 } 2186 2187 __private_extern__ 2188 void 1965 2189 swap_dylib_table_of_contents( 1966 2190 struct dylib_table_of_contents *tocs, -
trunk/Cocoa/F-Script Anywhere/Source/libMatch.c
r7 r217 40 40 #include <string.h> 41 41 #include <mach-o/loader.h> 42 #include "stuff/bytesex.h"42 //#include "stuff/bytesex.h" 43 43 #include "stuff/ofile.h" 44 44 -
trunk/Cocoa/F-Script Anywhere/Source/mach_inject/mach_inject.c
r153 r217 1 /**************************************************************************************** 2 mach_inject.c $Revision: 1.1.1.1 $ 3 4 Copyright (c) 2003 Red Shed Software. All rights reserved. 5 by Jonathan 'Wolf' Rentzsch (jon * redshed * net) 6 7 ************************************************************************************/ 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 1 /******************************************************************************* 2 mach_inject.c 3 Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> 4 Some rights reserved: <http://creativecommons.org/licenses/by/2.0/> 5 6 ***************************************************************************/ 12 7 13 8 #include "mach_inject.h" 14 9 15 #include <mach-o/dyld.h> 16 #include <mach-o/getsect.h> 17 #include <mach/message.h> 18 #include <mach/mach.h> 19 #include <sys/stat.h> 20 #include <assert.h> 21 #include <stdio.h> 22 #include <errno.h> 23 24 /* doesn't show up, for some reason */ 25 void bzero(void *, size_t); 26 27 #ifdef __cplusplus 28 } 29 #endif 30 31 #ifndef COMPILE_TIME_ASSERT 10 #include <mach-o/dyld.h> 11 #include <mach-o/getsect.h> 12 #include <mach/mach.h> 13 #include <sys/stat.h> 14 #include <sys/errno.h> 15 #include <assert.h> 16 #include <stdlib.h> // for malloc() 17 #include <stdio.h> // for printf() 18 #include <mach-o/fat.h> // for fat structure decoding 19 #include <mach-o/arch.h> // to know which is local arch 20 #include <fcntl.h> // for open/close 21 // for mmap() 22 #include <sys/types.h> 23 #include <sys/mman.h> 24 25 #ifndef COMPILE_TIME_ASSERT( exp ) 32 26 #define COMPILE_TIME_ASSERT( exp ) { switch (0) { case 0: case (exp):; } } 33 27 #endif 34 #define ASSERT_CAST( CAST_TO, CAST_FROM ) COMPILE_TIME_ASSERT( sizeof(CAST_TO)==sizeof(CAST_FROM) ) 35 36 /**************************************************************************************** 28 #define ASSERT_CAST( CAST_TO, CAST_FROM ) \ 29 COMPILE_TIME_ASSERT( sizeof(CAST_TO)==sizeof(CAST_FROM) ) 30 31 #if defined(__i386__) 32 void* fixedUpImageFromImage ( 33 const void *image, 34 unsigned long imageSize, 35 unsigned int jumpTableOffset, 36 unsigned int jumpTableSize, 37 ptrdiff_t fixUpOffset); 38 #endif /* __i386__ */ 39 40 /******************************************************************************* 37 41 * 38 42 * Interface 39 43 * 40 ******************************************************************************* *********/44 *******************************************************************************/ 41 45 #pragma mark - 42 46 #pragma mark (Interface) … … 48 52 size_t paramSize, 49 53 pid_t targetProcess, 50 vm_size_t stackSize ) {51 ;//assertCodePtr( threadEntry ); 52 ;//assertPtrIfNotNull( paramBlock);53 ;//assertPositive( targetProcess);54 ;//assertIsTrue( stackSize == 0 || stackSize > 1024 );54 vm_size_t stackSize ) 55 { 56 assert( threadEntry ); 57 assert( targetProcess > 0 ); 58 assert( stackSize == 0 || stackSize > 1024 ); 55 59 56 60 // Find the image. 57 61 const void *image; 58 62 unsigned long imageSize; 59 mach_error_t err = machImageForPointer( threadEntry, &image, &imageSize ); 60 63 unsigned int jumpTableOffset; 64 unsigned int jumpTableSize; 65 mach_error_t err = machImageForPointer( threadEntry, &image, &imageSize, &jumpTableOffset, &jumpTableSize ); 66 61 67 // Initialize stackSize to default if requested. 62 68 if( stackSize == 0 ) 63 /** @bug We only want an 8K default, fix the plop-in-the-middle code below. */ 69 /** @bug 70 We only want an 8K default, fix the plop-in-the-middle code below. 71 */ 64 72 stackSize = 16 * 1024; 65 73 66 74 // Convert PID to Mach Task ref. 67 75 mach_port_t remoteTask = 0; 68 if( !err ) 76 if( !err ) { 69 77 err = task_for_pid( mach_task_self(), targetProcess, &remoteTask ); 70 71 /** @todo Would be nice to just allocate one block for both the remote stack 72 *and* the remoteCode (including the parameter data block once that's 73 written. 78 #if defined(__i386__) 79 if (err == 5) fprintf(stderr, "Could not access task for pid %d. You probably need to add user to procmod group\n", targetProcess); 80 #endif 81 } 82 83 /** @todo 84 Would be nice to just allocate one block for both the remote stack 85 *and* the remoteCode (including the parameter data block once that's 86 written. 74 87 */ 75 88 76 89 // Allocate the remoteStack. 77 vm_address_t remoteStack = NULL;90 vm_address_t remoteStack = (vm_address_t)NULL; 78 91 if( !err ) 79 92 err = vm_allocate( remoteTask, &remoteStack, stackSize, 1 ); 80 93 81 94 // Allocate the code. 82 vm_address_t remoteCode = NULL;95 vm_address_t remoteCode = (vm_address_t)NULL; 83 96 if( !err ) 84 97 err = vm_allocate( remoteTask, &remoteCode, imageSize, 1 ); 85 98 if( !err ) { 86 99 ASSERT_CAST( pointer_t, image ); 100 #if defined (__ppc__) || defined (__ppc64__) 87 101 err = vm_write( remoteTask, remoteCode, (pointer_t) image, imageSize ); 102 #elif defined (__i386__) 103 // on intel, jump table use relative jump instructions (jmp), which means 104 // the offset needs to be corrected. We thus copy the image and fix the offset by hand. 105 ptrdiff_t fixUpOffset = (ptrdiff_t) (image - remoteCode); 106 void * fixedUpImage = fixedUpImageFromImage(image, imageSize, jumpTableOffset, jumpTableSize, fixUpOffset); 107 err = vm_write( remoteTask, remoteCode, (pointer_t) fixedUpImage, imageSize ); 108 free(fixedUpImage); 109 #endif 88 110 } 89 111 90 112 // Allocate the paramBlock if specified. 91 vm_address_t remoteParamBlock = NULL;113 vm_address_t remoteParamBlock = (vm_address_t)NULL; 92 114 if( !err && paramBlock != NULL && paramSize ) { 93 115 err = vm_allocate( remoteTask, &remoteParamBlock, paramSize, 1 ); 94 116 if( !err ) { 95 117 ASSERT_CAST( pointer_t, paramBlock ); 96 err = vm_write( remoteTask, remoteParamBlock, (pointer_t) paramBlock, paramSize ); 118 err = vm_write( remoteTask, remoteParamBlock, 119 (pointer_t) paramBlock, paramSize ); 97 120 } 98 121 } … … 101 124 ptrdiff_t threadEntryOffset, imageOffset; 102 125 if( !err ) { 103 ;//assertIsWithinRange( threadEntry, image, image+imageSize);126 //assert( (void*)threadEntry >= image && (void*)threadEntry <= (image+imageSize) ); 104 127 ASSERT_CAST( void*, threadEntry ); 105 threadEntryOffset = (( long) threadEntry) - (long)image;128 threadEntryOffset = ((void*) threadEntry) - image; 106 129 107 130 ASSERT_CAST( void*, remoteCode ); 108 imageOffset = (( long) remoteCode) - (long)image;131 imageOffset = ((void*) remoteCode) - image; 109 132 } 110 133 111 134 // Allocate the thread. 112 135 thread_act_t remoteThread; 136 #if defined (__ppc__) || defined (__ppc64__) 113 137 if( !err ) { 114 138 ppc_thread_state_t remoteThreadState; 115 139 116 /** @bug Stack math should be more sophisticated than this (ala redzone). */ 140 /** @bug 141 Stack math should be more sophisticated than this (ala redzone). 142 */ 117 143 remoteStack += stackSize / 2; 118 144 … … 139 165 remoteThreadState.lr = (unsigned int) 0xDEADBEEF; 140 166 167 #if 0 141 168 printf( "remoteCode start: %p\n", (void*) remoteCode ); 142 169 printf( "remoteCode size: %ld\n", imageSize ); 143 170 printf( "remoteCode pc: %p\n", (void*) remoteThreadState.srr0 ); 144 printf( "remoteCode end: %p\n", (void*) (((char*)remoteCode)+imageSize) ); 171 printf( "remoteCode end: %p\n", 172 (void*) (((char*)remoteCode)+imageSize) ); 145 173 fflush(0); 174 #endif 146 175 147 176 err = thread_create_running( remoteTask, PPC_THREAD_STATE, … … 149 178 &remoteThread ); 150 179 } 180 #elif defined (__i386__) 181 if( !err ) { 182 183 i386_thread_state_t remoteThreadState; 184 bzero( &remoteThreadState, sizeof(remoteThreadState) ); 185 186 vm_address_t dummy_thread_struct = remoteStack; 187 remoteStack += (stackSize / 2); // this is the real stack 188 // (*) increase the stack, since we're simulating a CALL instruction, which normally pushes return address on the stack 189 remoteStack -= 4; 190 191 #define PARAM_COUNT 4 192 #define STACK_CONTENTS_SIZE ((1+PARAM_COUNT) * sizeof(unsigned int)) 193 unsigned int stackContents[1 + PARAM_COUNT]; // 1 for the return address and 1 for each param 194 // first entry is return address (see above *) 195 stackContents[0] = 0xDEADBEEF; // invalid return address. 196 // then we push function parameters one by one. 197 stackContents[1] = imageOffset; 198 stackContents[2] = remoteParamBlock; 199 stackContents[3] = paramSize; 200 // We use the remote stack we allocated as the fake thread struct. We should probably use a dedicated memory zone. 201 // We don't fill it with 0, vm_allocate did it for us 202 stackContents[4] = dummy_thread_struct; 203 204 // push stackContents 205 err = vm_write( remoteTask, remoteStack, 206 (pointer_t) stackContents, STACK_CONTENTS_SIZE); 207 208 // set remote Program Counter 209 remoteThreadState.eip = (unsigned int) (remoteCode); 210 remoteThreadState.eip += threadEntryOffset; 211 212 // set remote Stack Pointer 213 ASSERT_CAST( unsigned int, remoteStack ); 214 remoteThreadState.esp = (unsigned int) remoteStack; 215 216 #if 0 217 printf( "remoteCode start: %p\n", (void*) remoteCode ); 218 printf( "remoteCode size: %ld\n", imageSize ); 219 printf( "remoteCode pc: %p\n", (void*) remoteThreadState.eip ); 220 printf( "remoteCode end: %p\n", 221 (void*) (((char*)remoteCode)+imageSize) ); 222 fflush(0); 223 #endif 224 // create thread and launch it 225 err = thread_create_running( remoteTask, i386_THREAD_STATE, 226 (thread_state_t) &remoteThreadState, i386_THREAD_STATE_COUNT, 227 &remoteThread ); 228 } 229 #else 230 #error architecture not supported 231 #endif 151 232 152 233 if( err ) { … … 166 247 const void *pointer, 167 248 const void **image, 168 unsigned long *size ) { 169 ;//assertCodePtr( pointer ); 170 ;//assertPtr( image ); 171 ;//assertPtr( size ); 249 unsigned long *size, 250 unsigned int *jumpTableOffset, 251 unsigned int *jumpTableSize ) 252 { 253 assert( pointer ); 254 assert( image ); 255 assert( size ); 172 256 173 257 unsigned long p = (unsigned long) pointer; 258 259 if (jumpTableOffset && jumpTableSize) { 260 *jumpTableOffset = 0; 261 *jumpTableSize = 0; 262 } 174 263 175 264 unsigned long imageIndex, imageCount = _dyld_image_count(); 176 265 for( imageIndex = 0; imageIndex < imageCount; imageIndex++ ) { 177 struct mach_header *header = _dyld_get_image_header( imageIndex ); 178 const struct section *section = getsectbynamefromheader( header, SEG_TEXT, SECT_TEXT ); 266 const struct mach_header *header = _dyld_get_image_header( imageIndex ); 267 const struct section *section = getsectbynamefromheader( header, 268 SEG_TEXT, 269 SECT_TEXT ); 179 270 long start = section->addr + _dyld_get_image_vmaddr_slide( imageIndex ); 180 271 long stop = start + section->size; 181 272 if( p >= start && p <= stop ) { 182 // It is tru ly insane we have to stat() the file system in order to183 // discover the size of an in-memory data structure.184 c har *imageName = _dyld_get_image_name( imageIndex );185 ;//assertPath( imageName );273 // It is truely insane we have to stat() the file system in order 274 // to discover the size of an in-memory data structure. 275 const char *imageName = _dyld_get_image_name( imageIndex ); 276 assert( imageName ); 186 277 struct stat sb; 187 278 if( stat( imageName, &sb ) ) … … 194 285 ;//assertUInt32( st_size ); 195 286 *size = sb.st_size; 287 288 // needed for Universal binaries. Check if file is fat and get image size from there. 289 int fd = open (imageName, O_RDONLY); 290 size_t mapSize = *size; 291 char * fileImage = mmap (NULL, mapSize, PROT_READ, MAP_FILE, fd, 0); 292 293 struct fat_header* fatHeader = (struct fat_header *)fileImage; 294 if (fatHeader->magic == OSSwapBigToHostInt32(FAT_MAGIC)) { 295 //printf("This is a fat binary\n"); 296 uint32_t archCount = OSSwapBigToHostInt32(fatHeader->nfat_arch); 297 298 NXArchInfo const *localArchInfo = NXGetLocalArchInfo(); 299 300 struct fat_arch* arch = (struct fat_arch *)(fileImage + sizeof(struct fat_header)); 301 struct fat_arch* matchingArch = NULL; 302 303 int archIndex = 0; 304 for (archIndex = 0; archIndex < archCount; archIndex++) { 305 cpu_type_t cpuType = OSSwapBigToHostInt32(arch[archIndex].cputype); 306 cpu_subtype_t cpuSubtype = OSSwapBigToHostInt32(arch[archIndex].cpusubtype); 307 308 if (localArchInfo->cputype == cpuType) { 309 matchingArch = arch + archIndex; 310 if (localArchInfo->cpusubtype == cpuSubtype) break; 311 } 312 } 313 314 if (matchingArch) { 315 *size = OSSwapBigToHostInt32(matchingArch->size); 316 //printf ("found arch-specific size : %p\n", *size); 317 } 318 } 319 320 munmap (fileImage, mapSize); 321 close (fd); 322 } 323 if (jumpTableOffset && jumpTableSize) { 324 const struct section * jumpTableSection = getsectbynamefromheader( header, 325 "__IMPORT", 326 "__jump_table" ); 327 if (jumpTableSection) { 328 *jumpTableOffset = jumpTableSection->offset; 329 *jumpTableSize = jumpTableSection->size; 330 } 196 331 } 197 332 return err_none; … … 201 336 return err_threadEntry_image_not_found; 202 337 } 338 339 #if defined(__i386__) 340 void* fixedUpImageFromImage ( 341 const void *image, 342 unsigned long imageSize, 343 unsigned int jumpTableOffset, 344 unsigned int jumpTableSize, 345 ptrdiff_t fixUpOffset) 346 { 347 // first copy the full image 348 void *fixedUpImage = (void *) malloc ((size_t)imageSize); 349 bcopy(image, fixedUpImage, imageSize); 350 351 // address of jump table in copied image 352 void *jumpTable = fixedUpImage + jumpTableOffset; 353 // each JMP instruction is 5 bytes (E9 xx xx xx xx) where E9 is the opcode for JMP 354 int jumpTableCount = jumpTableSize / 5; 355 356 // skip first "E9" 357 jumpTable++; 358 359 int entry=0; 360 for (entry = 0; entry < jumpTableCount; entry++) { 361 unsigned int jmpValue = *((unsigned int *)jumpTable); 362 jmpValue += fixUpOffset; 363 *((unsigned int *)jumpTable) = jmpValue; 364 jumpTable+=5; 365 } 366 367 return fixedUpImage; 368 } 369 #endif /* __i386__ */ -
trunk/Cocoa/F-Script Anywhere/Source/mach_inject/mach_inject.h
r153 r217 1 /**************************************************************************************** 2 mach_inject.h $Revision: 1.1.1.1 $ 1 /******************************************************************************* 2 mach_inject.h 3 Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> 4 Some rights reserved: <http://creativecommons.org/licenses/by/2.0/> 5 6 ***************************************************************************/ 3 7 4 Copyright (c) 2003 Red Shed Software. All rights reserved. 5 by Jonathan 'Wolf' Rentzsch (jon * redshed * net) 8 /***************************************************************************//** 9 @mainpage mach_inject 10 @author Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> 6 11 7 ************************************************************************************/ 8 9 /************************************************************************************/ /** 10 @mainpage mach_inject 11 @author Jonathan 'Wolf' Rentzsch (jon * redshed * net) 12 13 This package, coded in C to the Mach API, allows you to "inject" code into an 14 arbitrary process. "Injection" means both 1) copying over the necessary code into the 15 target's address space and 2) remotely creating a new thread to execute the code. 12 This package, coded in C to the Mach API, allows you to "inject" code into 13 an arbitrary process. "Injection" means both 1) copying over the necessary 14 code into the target's address space and 2) remotely creating a new thread 15 to execute the code. 16 16 17 *************************************************************************** *********/17 ***************************************************************************/ 18 18 19 19 #ifndef _mach_inject_ 20 20 #define _mach_inject_ 21 21 22 #ifdef __cplusplus23 extern "C" {24 #endif25 26 22 #include <sys/types.h> 27 23 #include <mach/error.h> 28 24 #include <mach/vm_types.h> 29 #include <stddef.h> 25 #include <stddef.h> // for ptrdiff_t 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 30 31 31 #define err_threadEntry_image_not_found (err_local|1) 32 #define err_threadEntry_init_failed (err_local|2)33 32 34 33 #define INJECT_ENTRY injectEntry 35 34 #define INJECT_ENTRY_SYMBOL "injectEntry" 36 35 37 typedef void (*mach_inject_entry)( ptrdiff_t codeOffset, void *paramBlock, size_t paramSize ); 36 typedef void (*mach_inject_entry)( ptrdiff_t codeOffset, void *paramBlock, 37 size_t paramSize, void* dummy_pthread_data ); 38 38 39 /*************************************************************************** *********//**39 /***************************************************************************//** 40 40 Starts executing threadEntry in a new thread in the process specified by 41 41 targetProcess. 42 42 43 @param threadEntry -> Required pointer to injected thread's entry point. 44 @param paramBlock -> Optional pointer to block of memory to pass to the 45 injected thread. 43 @param threadEntry -> Required pointer to injected thread's entry 44 point. 45 @param paramBlock -> Optional pointer to block of memory to pass to 46 the injected thread. 46 47 @param paramSize -> Optional size of paramBlock. 47 48 @param targetProcess -> Required target process ID. 48 @param stackSize -> Optional stack size of threadEntry's thread. Set to zero49 for default (currently 8K usable).49 @param stackSize -> Optional stack size of threadEntry's thread. Set 50 to zero for default (currently 8K usable). 50 51 @result <- mach_error_t 51 52 52 *************************************************************************** *********/53 ***************************************************************************/ 53 54 54 55 mach_error_t … … 60 61 vm_size_t stackSize ); 61 62 62 /*************************************************************************** *********//**63 /***************************************************************************//** 63 64 Given a pointer, returns its Mach-O image and image size. 64 65 65 @param pointer -> Required pointer. 66 @param image <- Optional returned pointer to image (really a mach_header). 67 @param size <- Optional returned size of the image. 68 @result <- mach_error_t 66 @param pointer -> Required pointer. 67 @param image <- Optional returned pointer to image (really a 68 mach_header). 69 @param size <- Optional returned size of the image. 70 @param jumpTableOffset <- Optional returned offset of jump table within image (useful on intel) 71 @param jumpTableSize <- Optional returned size of jump table (useful on intel) 72 @result <- mach_error_t 69 73 70 *************************************************************************** *********/74 ***************************************************************************/ 71 75 72 76 mach_error_t … … 74 78 const void *pointer, 75 79 const void **image, 76 unsigned long *size ); 80 unsigned long *size, 81 unsigned int *jumpTableOffset, 82 unsigned int *jumpTableSize ); 77 83 78 #ifdef 79 }84 #ifdef __cplusplus 85 } 80 86 #endif 81 82 87 #endif // _mach_inject_
Note:
See TracChangeset
for help on using the changeset viewer.