• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 //#include <cutils/misc.h>
3 
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sched.h>
9 #include <errno.h>
10 
11 #include <signal.h>
12 #include <sys/ptrace.h>
13 #include <sys/wait.h>
14 #include <sys/socket.h>
15 
16 #include <pthread.h>
17 
18 #include <cutils/sockets.h>
19 
20 void crash1(void);
21 void crashnostack(void);
22 void maybeabort(void);
23 int do_action(const char* arg);
24 
debuggerd_connect()25 static void debuggerd_connect()
26 {
27     char tmp[1];
28     int s;
29     sprintf(tmp, "%d", gettid());
30     s = socket_local_client("android:debuggerd",
31             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
32     if(s >= 0) {
33         read(s, tmp, 1);
34         close(s);
35     }
36 }
37 
smash_stack(int i)38 int smash_stack(int i) {
39     printf("crasher: deliberately corrupting stack...\n");
40     // Unless there's a "big enough" buffer on the stack, gcc
41     // doesn't bother inserting checks.
42     char buf[8];
43     // If we don't write something relatively unpredicatable
44     // into the buffer and then do something with it, gcc
45     // optimizes everything away and just returns a constant.
46     *(int*)(&buf[7]) = (uintptr_t) &buf[0];
47     return *(int*)(&buf[0]);
48 }
49 
test_call1()50 void test_call1()
51 {
52     *((int*) 32) = 1;
53 }
54 
test_thread(void * x)55 void *test_thread(void *x)
56 {
57     printf("crasher: thread pid=%d tid=%d\n", getpid(), gettid());
58 
59     sleep(1);
60     test_call1();
61     printf("goodbye\n");
62 
63     return 0;
64 }
65 
noisy(void * x)66 void *noisy(void *x)
67 {
68     char c = (unsigned) x;
69     for(;;) {
70         usleep(250*1000);
71         write(2, &c, 1);
72         if(c == 'C') *((unsigned*) 0) = 42;
73     }
74     return 0;
75 }
76 
ctest()77 int ctest()
78 {
79     pthread_t thr;
80     pthread_attr_t attr;
81     pthread_attr_init(&attr);
82     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
83     pthread_create(&thr, &attr, noisy, (void*) 'A');
84     pthread_create(&thr, &attr, noisy, (void*) 'B');
85     pthread_create(&thr, &attr, noisy, (void*) 'C');
86     for(;;) ;
87     return 0;
88 }
89 
thread_callback(void * raw_arg)90 static void* thread_callback(void* raw_arg)
91 {
92     return (void*) do_action((const char*) raw_arg);
93 }
94 
do_action_on_thread(const char * arg)95 int do_action_on_thread(const char* arg)
96 {
97     pthread_t t;
98     pthread_create(&t, NULL, thread_callback, (void*) arg);
99     void* result = NULL;
100     pthread_join(t, &result);
101     return (int) result;
102 }
103 
crash3(int a)104 __attribute__((noinline)) int crash3(int a) {
105    *((int*) 0xdead) = a;
106    return a*4;
107 }
108 
crash2(int a)109 __attribute__((noinline)) int crash2(int a) {
110    a = crash3(a) + 2;
111    return a*3;
112 }
113 
crash(int a)114 __attribute__((noinline)) int crash(int a) {
115    a = crash2(a) + 1;
116    return a*2;
117 }
118 
do_action(const char * arg)119 int do_action(const char* arg)
120 {
121     if(!strncmp(arg, "thread-", strlen("thread-"))) {
122         return do_action_on_thread(arg + strlen("thread-"));
123     }
124 
125     if(!strcmp(arg,"smash-stack")) return smash_stack(42);
126     if(!strcmp(arg,"nostack")) crashnostack();
127     if(!strcmp(arg,"ctest")) return ctest();
128     if(!strcmp(arg,"exit")) exit(1);
129     if(!strcmp(arg,"crash")) return crash(42);
130     if(!strcmp(arg,"abort")) maybeabort();
131 
132     pthread_t thr;
133     pthread_attr_t attr;
134     pthread_attr_init(&attr);
135     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
136     pthread_create(&thr, &attr, test_thread, 0);
137     while(1) sleep(1);
138 }
139 
main(int argc,char ** argv)140 int main(int argc, char **argv)
141 {
142     fprintf(stderr,"crasher: built at " __TIME__ "!@\n");
143     fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid());
144 
145     if(argc > 1) {
146         return do_action(argv[1]);
147     } else {
148         crash1();
149 //        *((int*) 0) = 42;
150     }
151 
152     return 0;
153 }
154 
maybeabort()155 void maybeabort()
156 {
157     if(time(0) != 42) abort();
158 }
159