int main(int argc, char *argv[]) { int keepRunning = 1; int command; while (keepRunning == 1) { showRegisters(); command = inputCommand(); switch (command) { case 0: keepRunning--; break; case 1: assignment(); break; case 2: addRegisters(); break; case 3: subtractRegisters(); break; } } return 0; }
//================================================================================================ // // powerStateDidChangeTo // //================================================================================================ // IOReturn AppleUSBUHCI::powerStateDidChangeTo ( IOPMPowerFlags capabilities, unsigned long newState, IOService* whichDevice) { USBTrace( kUSBTUHCI, KTPUHCIPowerState, (uintptr_t)this, newState, 0, 2); USBLog(5, "AppleUSBUHCI[%p]::powerStateDidChangeTo new state (%d)", this, (int)newState); showRegisters(7, "powerStateDidChangeTo"); return super::powerStateDidChangeTo(capabilities, newState, whichDevice); }
int main(void) { unsigned long int registers[12]; showRegisters(registers, 12); printf("\nsuma:%d\tresta:%d\tAND:%d\tOR:%d\tXOR:%d\n",suma(registers[1],registers[2]),resta(registers[1],registers[2]),ANDS(registers[1],registers[2]),ORES(registers[1],registers[2]),XOR(registers[1],registers[2])); }
//================================================================================================ // // powerChangeDone // //================================================================================================ // void AppleUSBUHCI::powerChangeDone ( unsigned long fromState) { unsigned long newState = getPowerState(); USBTrace( kUSBTUHCI, KTPUHCIPowerState, (uintptr_t)this, fromState, newState, 3); USBLog((fromState == newState) || !_controllerAvailable ? 7 : 5, "AppleUSBUHCI[%p]::powerChangeDone from state (%d) to state (%d) _controllerAvailable(%s)", this, (int)fromState, (int)newState, _controllerAvailable ? "true" : "false"); if (_controllerAvailable) showRegisters(7, "powerChangeDone"); super::powerChangeDone(fromState); }
//================================================================================================ // // DozeController // //================================================================================================ // IOReturn AppleUSBUHCI::DozeController(void) { UInt16 cmd; int i; bool portsBeingResumed = false; USBTrace( kUSBTUHCI, KTPUHCIDozeController, (uintptr_t)this, 0, 0, 0); USBLog(6, "AppleUSBUHCI[%p]::DozeController", this); for (i=0; i<kUHCI_NUM_PORTS; i++) { if (_rhPortBeingResumed[i]) { USBLog(1, "AppleUSBUHCI[%p]::DozeController - port (%d) is being resumed. not stopping the controller", this, i+1); portsBeingResumed = true; } } if (!portsBeingResumed) { showRegisters(7, "+DozeController - stopping controller"); Run(false); // In order to get a Resume Detected interrupt, the controller needs to be in Global suspend mode, so we will do that even when "dozing". USBLog(6, "AppleUSBUHCI[%p]::DozeController Globally suspending", this); // Put the controller in Global Suspend cmd = ioRead16(kUHCI_CMD) & ~kUHCI_CMD_FGR; cmd |= kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); _myBusState = kUSBBusStateSuspended; IOSleep(3); } return kIOReturnSuccess; }
static DebugWaitFor dbgShowRegisters(char *line, processPo p, termPo loc, insWord ins, void *cl) { showRegisters(p, p->heap, p->prog, p->pc, p->fp, p->sp); resetDeflt("n"); return moreDebug; }
int loadExtension(int pid, char *path, int isBeingDebugged) { uintptr_t dlopen; uintptr_t str; int status; int pathlen=strlen(path)+1; //0-terminater printf("loadExtension(%d, %s, %d)\n", pid, path, isBeingDebugged); printf("Phase 0: Check if it's already open\n"); if (isExtensionLoaded(pid)) { printf("Already loaded\n"); return TRUE; } else printf("Not yet loaded\n"); printf("Phase 1: Find dlopen in target\n"); dlopen=finddlopen(pid); printf("dlopen=%p\n", (void *)dlopen); if (!isBeingDebugged) { ptrace(PTRACE_ATTACH, pid, 0,0); pid=WaitForPid(); printf("After wait. PID=%d\n", pid); ptrace(PTRACE_CONT,pid,0,0); } printf("Killing pid %d\n", pid); int e=kill(pid, SIGSTOP); printf("kill returned %d\n", e); printf("Waiting...\n"); pid=WaitForPid(); showRegisters(pid); printf("After wait 2. PID=%d\n", pid); //save the current state and set the state to what I need it to be #ifdef __arm__ struct pt_regs origregs; struct pt_regs newregs; #else struct user_regs_struct origregs; char bla[1024]; struct user_regs_struct newregs; char bla2[1024]; #endif if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0) { printf("PTRACE_GETREGS FAILED\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_GETREGS, pid, 0, &origregs)!=0) { printf("PTRACE_GETREGS FAILED 2\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } uintptr_t returnaddress=0x0ce0; #ifdef __arm__ //allocate space in the stack newregs.ARM_sp-=8+4*((pathlen+3)/ 4); //not sur eif [sp] is written to with a push or if it's [sp-4] and then sp decreased, so start at sp+4 instead str=newregs.ARM_sp+4; writeString(pid, str, path); newregs.ARM_lr=returnaddress; newregs.ARM_pc=dlopen; newregs.ARM_r0=str; newregs.ARM_r1=RTLD_NOW; if (newregs.ARM_pc & 1) { //THUMB Address link printf("THUMB destination\n"); newregs.ARM_cpsr=newregs.ARM_cpsr | (1 << 5); //not sure how to set the J bit (thumbee uses it...) //for now disable it until a bug happens newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<25)); //unset J } else { printf("ARM destination\n"); printf("newregs.ARM_cpsr was %x\n", newregs.ARM_cpsr); newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<5)); //unset T newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<25)); //unset J printf("newregs.ARM_cpsr is %x\n", newregs.ARM_cpsr); } printf("r0=%lx\n", origregs.ARM_r0); printf("orig_r0=%lx\n", origregs.ARM_ORIG_r0); printf("pc=%lx\n", origregs.ARM_pc); printf("cpsr=%lx\n", origregs.ARM_cpsr); #else #ifdef __x86_64__ printf("rax=%lx\n", origregs.rax); printf("rbp=%lx\n", origregs.rbp); printf("rsp=%lx\n", origregs.rsp); printf("orig_rax=%lx\n", origregs.orig_rax); printf("rip=%lx\n", origregs.rip); //allocate stackspace newregs.rsp=newregs.rsp-0x28-(8*((pathlen+7) / 8)); //check that the first 4 bits of rsp are 1000 (8) (aligned with the function return push) if ((newregs.rsp & 0xf)!=8) { printf("Aligning stack. Was %llx", newregs.rsp); newregs.rsp-=8; newregs.rsp&=~(0xf); //clear the first 4 bits newregs.rsp=newregs.rsp | 8; //set to 8 printf(" is now %llx\n", newregs.rsp); } //set the return address printf("Writing 0x0ce0 to %lx\n", newregs.rsp); if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp, returnaddress)!=0) { printf("Failed to write return address\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp-8, returnaddress)!=0) { printf("F**k\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp+8, returnaddress)!=0) { printf("F**k\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } //write the path at rsp+10 str=newregs.rsp+0x18; writeString(pid, str, path); printf("str=%p\n", (void *)str); returnaddress=ptrace(PTRACE_PEEKDATA, pid, newregs.rsp, 0); printf("[%lx]=%lx", newregs.rsp, returnaddress); newregs.rip=dlopen; //+2 //(test) newregs.rax=0; newregs.rdi=str; newregs.rsi=RTLD_NOW; newregs.orig_rax=0; #else printf("32-bit is not yet supported\n"); printf("eax=%lx\n", origregs.eax); printf("ebp=%lx\n", origregs.ebp); printf("esp=%lx\n", origregs.esp); printf("orig_eax=%lx\n", origregs.orig_eax); printf("eip=%lx\n", origregs.eip); //allocate stackspace newregs.esp=newregs.esp-0x28-(8*((pathlen+7) / 8)); if ((newregs.esp & 0xf)!=8) { printf("Aligning stack. Was %llx", newregs.esp); newregs.esp-=8; newregs.esp&=~(0xf); //clear the first 4 bits newregs.esp=newregs.esp | 8; //set to 8 printf(" is now %llx\n", newregs.esp); } //in 32-bit the stack will have to look like: //0-3: Return address (0x0ce0) //4-7: Address to path //8-11:RTLD_NOW //12-...: Path // if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+0, returnaddress)!=0) { printf("F**k\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+4, newregs.esp+12)!=0) { printf("Fuck2\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+8, RTLD_NOW)!=0) { printf("Fuck3\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } writeString(pid, newregs.esp+12, path); newregs.eip=dlopen; newregs.orig_eax=0; #endif //__x86_64 #endif if (ptrace(PTRACE_SETREGS, pid, 0, &newregs)!=0) { printf("PTRACE_SETREGS FAILED\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0) { printf("PTRACE_GETREGS FAILED 4\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } printf("after setregs:\n"); #ifdef __arm__ printf("r0=%lx\n", newregs.ARM_r0); printf("orig_r0=%lx\n", newregs.ARM_ORIG_r0); printf("pc=%lx\n", newregs.ARM_pc); printf("cpsr=%lx\n", newregs.ARM_cpsr); #else #ifdef __x86_64__ printf("rax=%lx\n", newregs.rax); printf("rdi=%lx\n", newregs.rdi); printf("rsi=%lx\n", newregs.rsi); printf("rbp=%lx\n", newregs.rbp); printf("rsp=%lx\n", newregs.rsp); printf("orig_rax=%lx\n", newregs.orig_rax); printf("rip=%lx\n", newregs.rip); #else printf("eax=%lx\n", newregs.eax); printf("edi=%lx\n", newregs.edi); printf("esi=%lx\n", newregs.esi); printf("ebp=%lx\n", newregs.ebp); printf("esp=%lx\n", newregs.esp); printf("orig_eax=%lx\n", newregs.orig_eax); printf("eip=%lx\n", newregs.eip); #endif //__x86_64__ #endif printf("\n\nContinuing thread\n"); int ptr; ptr=ptrace(PTRACE_CONT,pid,(void *)0,(void *)SIGCONT); printf("PRACE_CONT=%d\n", ptr); if (ptr!=0) { printf("PTRACE_CONT FAILED\n"); return 1; } //wait for this thread to crash pid=-1; while (pid==-1) { pid=waitpid(-1, &status, WUNTRACED| __WALL); if ((pid==-1) && (errno!=EINTR)) { printf("LoadExtension wait fail. :%d\n", errno); return FALSE; } if (pid==0) pid=-1; printf("."); } printf("after wait: pid=%d (status=%x)\n", pid, status); siginfo_t si; if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)!=0) { printf("GETSIGINFO FAILED\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } printf("si.si_signo=%d\n", si.si_signo); if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0) { printf("PTRACE_GETREGS FAILED (2)\n"); ptrace(PTRACE_DETACH, pid,0,0); return FALSE; } #ifdef __arm__ printf("r0=%lx\n", newregs.ARM_r0); printf("orig_r0=%lx\n", newregs.ARM_ORIG_r0); printf("pc=%lx\n", newregs.ARM_pc); printf("sp=%lx\n", newregs.ARM_sp); printf("cpsr=%lx\n", newregs.ARM_cpsr); #else #ifdef __x86_64__ printf("rax=%lx\n", newregs.rax); printf("rdi=%lx\n", newregs.rdi); printf("rsi=%lx\n", newregs.rsi); printf("rbp=%lx\n", newregs.rbp); printf("rsp=%lx\n", newregs.rsp); printf("orig_rax=%lx\n", newregs.rax); printf("rip=%lx\n", newregs.rip); #else printf("eax=%lx\n", newregs.eax); printf("edi=%lx\n", newregs.edi); printf("esi=%lx\n", newregs.esi); printf("ebp=%lx\n", newregs.ebp); printf("esp=%lx\n", newregs.esp); printf("orig_eax=%lx\n", newregs.eax); printf("eip=%lx\n", newregs.eip); #endif #endif if (ptrace(PTRACE_SETREGS, pid, 0, &origregs)!=0) { printf("PTRACE_SETREGS FAILED (20\n"); } if (!isBeingDebugged) { printf("Detaching\n"); if (ptrace(PTRACE_DETACH, pid,0,0)!=0) printf("PTRACE_DETACH FAILED\n"); } else { if (ptrace(PTRACE_CONT,pid,(void *)0,(void *)SIGCONT)!=0) printf("PTRACE_CONT failed\n"); } printf("End...\n"); }
//================================================================================================ // // WakeControllerFromDoze // //================================================================================================ // IOReturn AppleUSBUHCI::WakeControllerFromDoze(void) { UInt16 cmd; int i; bool portHasRD[kUHCI_NUM_PORTS]; UInt16 status; USBTrace( kUSBTUHCI, KTPUHCIWakeFromDoze, (uintptr_t)this, 0, 0, 0); // First, see if we have any ports that have the RD bit set. If they do, then we can go ahead and clear it after we waited the 20ms for the // Global resume for (i=0; i<kUHCI_NUM_PORTS; i++) { status = ReadPortStatus(i); if (status & kUHCI_PORTSC_RD) { USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller port %d has kUHCI_PORTSC_RD set", this, i+1); portHasRD[i] = true; } else { portHasRD[i] = false; } } // If we are in Global Suspend mode, we need to resume the controller. We will wait 20ms with the gate held. However, since we only // get into this mode if all devices are suspended, then delaying while holding the wl will not prevent any completions from happening, since // there aren't any. cmd = ioRead16(kUHCI_CMD); if (cmd & kUHCI_CMD_EGSM) { USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller is globally suspended - forcing resume", this); cmd |= kUHCI_CMD_FGR; ioWrite16(kUHCI_CMD, cmd); cmd = ioRead16(kUHCI_CMD); USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze after EGSM->FGR, cmd is[%p], sleeping 20ms", this, (void*)cmd); IOSleep(20); cmd &= ~kUHCI_CMD_FGR; cmd &= ~kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); // Clear any RD bits in the port if they were set, now that we have waited 20ms for (i=0; i<kUHCI_NUM_PORTS; i++) { if (portHasRD[i] ) { status = ReadPortStatus(i) & kUHCI_PORTSC_MASK; status &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND); USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze de-asserting resume signal for port %d by writing (%p)", this, i+1, (void*)status); WritePortStatus(i, status); IOSync(); IOSleep(2); // allow it to kick in } } } USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze calling Run(true)", this); Run(true); _myBusState = kUSBBusStateRunning; showRegisters(7, "-WakeControllerFromDoze"); return kIOReturnSuccess; }
//================================================================================================ // // ResumeController // //================================================================================================ // void AppleUSBUHCI::ResumeController(void) { UInt16 cmd; int i; USBTrace( kUSBTUHCI, KTPUHCIResumeController , (uintptr_t)this, 0, 0, 0); showRegisters(7, "+ResumeController"); cmd = ioRead16(kUHCI_CMD); if (cmd & kUHCI_CMD_RS) { USBLog(3, "AppleUSBUHCI[%p]::ResumeController - already running - returning", this); return; } // I need to save the existing frame list before I turn on processing so I can send SOF only for 10ms after we turn the controller on for (i=0;i < kUHCI_NVFRAMES; i++) { _frameList[i] |= HostToUSBLong(kUHCI_FRAME_T); } if (cmd & kUHCI_CMD_EGSM) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController controller is globally suspended - forcing resume", this); cmd |= kUHCI_CMD_FGR; ioWrite16(kUHCI_CMD, cmd); cmd = ioRead16(kUHCI_CMD); USBLog(5, "AppleUSBUHCI[%p]::ResumeController after EGSM->FGR, cmd is[%p]", this, (void*)cmd); } if (cmd & kUHCI_CMD_FGR) { // this could either be because the remote wwakeup caused this state or because we did above // need to wait 20ms IOSleep(20); cmd &= ~kUHCI_CMD_FGR; cmd &= ~kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); } if ((cmd & (kUHCI_CMD_MAXP | kUHCI_CMD_CF)) != (kUHCI_CMD_MAXP | kUHCI_CMD_CF)) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController marking MAXP and CF", this); cmd |= (kUHCI_CMD_MAXP | kUHCI_CMD_CF); ioWrite16(kUHCI_CMD, cmd); } // restore the frame list register if (_framesPaddr != NULL) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController setting FRBASEADDR[%p]", this, (void*)_framesPaddr); ioWrite32(kUHCI_FRBASEADDR, _framesPaddr); } USBLog(5, "AppleUSBUHCI[%p]::ResumeController starting controller", this); Run(true); // wait 10 ms for the device to recover IOSleep(10); // restore the list for (i=0;i < kUHCI_NVFRAMES; i++) { _frameList[i] &= ~HostToUSBLong(kUHCI_FRAME_T); } USBLog(7, "AppleUSBUHCI[%p]::ResumeController resume done, cmd %x, status %x ports[%p, %p]", this, ioRead16(kUHCI_CMD), ioRead16(kUHCI_STS),(void*)ReadPortStatus(0), (void*)ReadPortStatus(1)); showRegisters(7, "-ResumeController"); }
/** Main menu **/ void menu() { int instrReturn; char choice; int bytesRead; unsigned offset, length; // initialize memory, declared in myMenu.h char memory[MEMSIZE]; // initialize registers and reset, declared in myMenu.h struct Registers myRegisters; reset(&myRegisters); while (1) { // display menu fprintf(stdout, "\n\n---------------------------------------------------"); fprintf(stdout, "\nSheranga Balasuriya: Welcome to my Virtual CPU\nPlease select one of the following"); fprintf(stdout, "\nd\tdump memory"); fprintf(stdout, "\ng\tgo"); fprintf(stdout, "\nl\tload a file into memory"); fprintf(stdout, "\nm\tmemory modify"); fprintf(stdout, "\nq\tquit"); fprintf(stdout, "\nr\tdisplay registers"); fprintf(stdout, "\nt\ttrace"); fprintf(stdout, "\nw\twrite file"); fprintf(stdout, "\nz\treset registers"); fprintf(stdout, "\nb\tenable/disable debugging"); fprintf(stdout, "\n? , h\tdisplay help\n"); fscanf(stdin, " %1c", &choice); flush(); // check choice taken switch (choice) { case 'd': case 'D': // get offset from user fprintf(stdout, "\nPleae enter the offset in hex: "); fscanf(stdin, "%x", &offset); flush(); // get length from user fprintf(stdout, "\nPlease enter the length in hex: "); fscanf(stdin, "%x", &length); flush(); memDump(memory, offset, length); break; case 'g': case 'G': go(&myRegisters,memory); break; case 'l': case 'L': bytesRead = loadFile(memory, MEMSIZE); if (bytesRead > 0) fprintf(stdout, "\n%d(0x%X) bytes read into memory", bytesRead, bytesRead); break; case 'm': case 'M': modify(memory); break; case 'q': case 'Q': return; break; case 'r': case 'R': showRegisters(&myRegisters); break; case 't': case 'T': instrReturn = instructionCycle(&myRegisters, memory); showRegisters(&myRegisters); break; case 'w': case 'W': writeFile(memory); break; case 'z': case 'Z': reset(&myRegisters); break; case 'b': case 'B': debug(&myRegisters); break; case '?': case 'h': case 'H': help(); break; default: fprintf(stdout, "\nIncorrect entry, try again"); } } }
IOReturn AppleUSBUHCI::RHSuspendPort(int port, bool suspended) { UInt16 cmd, value; USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) _rhPortBeingResumed[%d](%s)", this, port, suspended ? "SUSPEND" : "RESUME", (int)port-1, _rhPortBeingResumed[port-1] ? "true" : "false"); showRegisters(7, "RHSuspendPort"); port--; // convert 1-based to 0-based. if (_rhPortBeingResumed[port]) { if (!suspended) { USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort - resume on port (%d) already being resumed - gracefully ignoring", this, (int)port+1); return kIOReturnSuccess; } USBLog(1, "AppleUSBUHCI[%p]::RHSuspendPort - trying to suspend port (%d) which is being resumed - UNEXPECTED", this, (int)port+1); USBTrace( kUSBTUHCI, kTPUHCIRHSuspendPort, (uintptr_t)this, (int)port+1, 0, 0); } cmd = ioRead16(kUHCI_CMD); value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; if (suspended) { value |= kUHCI_PORTSC_SUSPEND; value &= ~kUHCI_PORTSC_RD; } else { if (cmd & kUHCI_CMD_EGSM) { /* Can't un-suspend a port during global suspend. */ USBError(1, "AppleUSBUHCI[%p]: attempt to resume during global suspend", this); return kIOReturnError; } value |= (kUHCI_PORTSC_SUSPEND | kUHCI_PORTSC_RD); } // Always enable the port also. value |= kUHCI_PORTSC_PED; USBLog(5, "AppleUSBUHCI[%p]: writing (%p) to port control", this, (void*)value); WritePortStatus(port, value); if (suspended) { /* Suspending. * Sleep for 3ms to ensure nothing goes out on the bus * until devices are suspended. */ IOSleep(3); } else { // Resuming USBLog(5,"AppleUSBUHCI[%p]::RHSuspendPort - resuming port %d, calling out to timer", this, (int)port+1); _rhPortBeingResumed[port] = true; thread_call_enter1(_rhResumePortTimerThread[port], (void*)(port+1)); } USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) calling UIMRootHubStatusChange", this, port+1, suspended ? "SUSPEND" : "RESUME"); UIMRootHubStatusChange(); USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) DONE", this, port+1, suspended ? "SUSPEND" : "RESUME"); return kIOReturnSuccess; }