ADB Shell을 설정하고 처리하는 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <stdio.h>
#include <stdlib.h>
 
#include <conio.h>
 
#include <windows.h>
 
#define MAX_LINE 4096
 
int main(int argc, char** argv)
{
    HANDLE write_in, write_out;
    HANDLE read_in, read_out;
 
    SECURITY_ATTRIBUTES sec;
 
    long unsigned int writen=0;
    long unsigned int readn=0;
 
    int rtv;
 
    char command[80= {0,};
    char buffer[MAX_LINE];
 
    STARTUPINFO si={0,};
    PROCESS_INFORMATION pi;
 
    //pthread
    pthread_t read_pthread;
    pthread_t write_pthread;
 
    sec.nLength=sizeof(SECURITY_ATTRIBUTES);
    sec.bInheritHandle=TRUE;
    sec.lpSecurityDescriptor=NULL;
 
    CreatePipe(&write_out,&write_in,&sec,0);
    CreatePipe(&read_in,&read_out,&sec,0);
 
    sprintf(command,"./adb.exe shell",NULL);
 
    si.cb=sizeof(STARTUPINFO);
    si.hStdInput=write_out;
    si.hStdOutput=read_out;
    si.dwFlags=STARTF_USESTDHANDLES;
 
    rtv=CreateProcess(NULL,
                      command,
                      NULL,
                      NULL,
                      TRUE,
                      NULL,
                      NULL,
                      NULL,
                      &si,
                      &pi);
 
    if(!rtv){
        printf("Error");
        return -1;
    }
 
    int i=0;
    int n = 0;
    char tmpkey=0;
 
    char filenames[100];
 
    FILE *fp=NULL;
 
    while(1){
 
        writen=0;
        readn=0;
 
        for(i=0;i<MAX_LINE;i++){
            buffer[i]=0x00;
        }
 
        //ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
        //ReadFile(read_in,buffer,sizeof(buffer),&readn,FILE_FLAG_OVERLAPPED);
        ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
 
        if(!strncmp(buffer,"exit",4)){
            break;
        }
 
        printf("%s",buffer);
 
        for(i=0;i<MAX_LINE;i++){
            buffer[i]=0x00;
        }
 
        fgets(buffer,MAX_LINE,stdin);
        //WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
 
        if(!strncmp(buffer,"exit\n",5)){
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            break;
        }
        WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
 
    }
 
    while(system("start ./adb.exe kill-server"));
 
    CloseHandle(write_in);
    CloseHandle(write_out);
    CloseHandle(read_in);
    CloseHandle(read_out);
 
    return 0;
}
 
cs


 이렇게하여, 출력이 가능하다.

 PIPE가 이상 없이 되기 위해서 설정하는 방법도 있다.

Posted by JunkMam
,

 ADB을 이용해서 안드로이드 자동화를 하기 위해선 명령어를 알 수 있어야 될 것이다.


 기본적으로 안드로이드의 액티비티를 작동시키기 위해서는 명령어는 am(Activity Menager)을 사용해야된다.


 예) am start -n com.android.activity/.Main


 이렇게 작동시킨다.


 규칙은 am start -n [Package Name]/.[Class Name][각주:1]이 된다.


 Package Name과 Class Name을 사용해야된다.


 이 Package Name과 Activity Name을 얻기 위해서는 명칭을 알아야 될 것이다.


 이걸 알아내기 위해선, 액티비티를 실행 했을때 알 수 있다.(다른 방법은 아직 조사 중이다.)


 명령어는 다음과 같다.


 예) dumpsys activity activities


 이렇게 하면, activity에 관련된 것으로, 메모리로 올라와 있는걸 설정되어 있다.


 한 번이라도 실행 되면, 자동으로 메모리 어딘가에 올라가 있으며, 이걸 확인 하기 위해서 sumpsys을 이용한다.


 그래서, am start을 실행 시키기 전에 dumpsys로 여는 방법이 중요하다.

 단, Root가 되어야지만 실행이 가능한 액티비티도 존재하기 때문에 잘 분석해서 사용해야 될 것이다.


 dumpsys의 내용을 나중에 기록한다.

  1. 정확하겐 Activity Name이다. [본문으로]
Posted by JunkMam
,

 ADB랑 연결한다고 해도, PIPE로 통신해야된다.

 방법은 다음과 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
    if(!rtv){
        printf("Error");
        return -1;
    }
 
    int i=0;
    int n = 0;
    char tmpkey=0;
 
    char filenames[100];
 
    FILE *fp=NULL;
 
    while(1){
 
        writen=0;
        readn=0;
 
        for(i=0;i<MAX_LINE;i++){
            buffer[i]=0x00;
        }
 
        //ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
        //ReadFile(read_in,buffer,sizeof(buffer),&readn,FILE_FLAG_OVERLAPPED);
        ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
 
        if(!strncmp(buffer,"exit",4)){
            break;
        }
 
        printf("%s",buffer);
 
        for(i=0;i<MAX_LINE;i++){
            buffer[i]=0x00;
        }
 
        fgets(buffer,MAX_LINE,stdin);
        //WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
 
        if(!strncmp(buffer,"exit\n",5)){
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            break;
        }
        WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
 
    }
 
cs


 이렇게 하면, WriteFile로 처리될 수 있다.

 ReadFile로 하면, 파이프로 적혀진 버퍼를 읽어들인다.

 WriteFile로 하면, 버퍼에 기록한다.


 이렇게 해서 ADB SHELL을 통신할 수 있다.

Posted by JunkMam
,

 안드로이드 자동화에서 PIPE을 STDIN[각주:1]과 STDOUT[각주:2]을 하는 방법을 알아봐야된다.

 이 방법을 기록한 블로그가 현재 검색이 되지 않아서 MS측에서 제공하는 것을 작성할려고 한다.[각주:3]


 여기에서 작동하는 방법을 이용하면, STDIN과 STDOUT을 받아서 처리할 수 있게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    HANDLE write_in, write_out;
    HANDLE read_in, read_out;
 
    SECURITY_ATTRIBUTES sec;
 
    long unsigned int writen=0;
    long unsigned int readn=0;
 
    int rtv;
 
    char command[80= {0,};
    char buffer[MAX_LINE];
 
    STARTUPINFO si={0,};
    PROCESS_INFORMATION pi;
 
    //pthread
    pthread_t read_pthread;
    pthread_t write_pthread;
 
    sec.nLength=sizeof(SECURITY_ATTRIBUTES);
    sec.bInheritHandle=TRUE;
    sec.lpSecurityDescriptor=NULL;
 
    CreatePipe(&write_out,&write_in,&sec,0);
    CreatePipe(&read_in,&read_out,&sec,0);
 
    sprintf(command,"./adb.exe shell",NULL);
 
    si.cb=sizeof(STARTUPINFO);
    si.hStdInput=write_out;
    si.hStdOutput=read_out;
    si.dwFlags=STARTF_USESTDHANDLES;
 
    rtv=CreateProcess(NULL,
                      command,
                      NULL,
                      NULL,
                      TRUE,
                      NULL,
                      NULL,
                      NULL,
                      &si,
                      &pi);
 
 
cs


 윗 같이 사용할 경우에, 입/출력 버퍼를 PIPE에 연결하여 처리할 수 있게 된다.

 이렇게 하면, ADB의 SHELL의 입/출력을 다른 쪽으로 연결되어서 처리하게 된다.

  1. STDIN(Standard Input) : 기본적으로 사용자가 키보드에 입력하는 것을 받아들이는 입력 버퍼 [본문으로]
  2. STDOUT (Standard Output) : 기본적으로 모니터에서 출력되는 것을 저장하는 출력 버퍼. [본문으로]
  3. https://support.microsoft.com/ko-kr/kb/190351(2015-06-13) [본문으로]
Posted by JunkMam
,

 안드로이드을 자동으로 컨트롤 하는 방법이 다양하다.

 여기서 ADB을 연결하여 안드로이드 자동화를 하는걸 목표로 공부한걸 기록하도록 한다.


 ADB[각주:1]를이용하면, 사용자가 폰을 건들지 않아도 Touch 이벤트를 일으킬 수 있다.

단, 여기서 매우 빠르게 필요한 경우면, 안 쓰는게 낫다.[각주:2]


 먼저, 자기가 만든 프로그램과 ADB랑 연결하는 방법을 기록한다.


 실행 프로그램과 PIPE로 연결 하기 위해선 FindWindows을 이용해야되지만, 이 방법은 자식 프로세서를 연결한다.


 CreateProcess라는 걸 이용하면, 자식 프로세서가 생성 및 실행이된다. 실행될 프로세서는 ADB이고, 부모 프로세서는 작성하는 프로그램이 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    STARTUPINFO si={0,};
    PROCESS_INFORMATION pi;
 
    char command[80= {0,};
 
    sprintf(command,"./adb.exe shell",NULL);
 
    si.cb=sizeof(STARTUPINFO);
    si.dwFlags=STARTF_USESTDHANDLES;
 
    rtv=CreateProcess(NULL,
                      command,
                      NULL,
                      NULL,
                      TRUE,
                      NULL,
                      NULL,
                      NULL,
                      &si,
                      &pi);
 
 
cs


 이렇게 추가하게 되면, adb의 shell과 연결이 되게 된다.

 차후에 STDIN과 STDOUT을 받는 방법을 기록하도록 한다.



  1. ADB란, Android DeBuger을 뜻한다. Android의 프로그램을 만들때나 기기를 점검할때 사용하기도 한다. [본문으로]
  2. ADB에선 이벤트를 보낼때, 아무리 빨라도 0.5초 가량의 시간이 들게 된다. [본문으로]
Posted by JunkMam
,