| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <sys/mman.h> |
| #include <sys/ioctl.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| |
| #define DEVICE "/dev/seemplog" |
| #define SZ_1M 0x100000 |
| #define FOUR_MB (4 * SZ_1M) |
| |
| #define BLK_SIZE 256 |
| #define BLK_HDR_SIZE 64 |
| #define TS_SIZE 20 |
| #define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE) |
| |
| #define TASK_COMM_LEN 16 |
| |
| #define MAGIC 'z' |
| |
| #define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int) |
| #define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2) |
| #define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int) |
| #define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int) |
| #define SEEMP_CMD_SET_MASK _IO(MAGIC, 5) |
| #define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6) |
| #define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int) |
| #define SEEMP_CMD_DEBUG_START _IOR(MAGIC, 8, int) |
| #define SEEMP_CMD_DEBUG_STOP _IOR(MAGIC, 9, int) |
| |
| struct read_range { |
| int start_idx; |
| int num; |
| }; |
| |
| struct blk_payload { |
| uint32_t api_id; |
| char msg[BLK_MAX_MSG_SZ]; |
| } __attribute__((packed)); |
| |
| struct seemp_logk_blk { |
| uint8_t status; |
| uint16_t len; |
| uint8_t version; |
| int32_t pid; |
| int32_t uid; |
| int32_t tid; |
| int32_t sec; |
| int32_t nsec; |
| char ts[TS_SIZE]; |
| char appname[TASK_COMM_LEN]; |
| struct blk_payload payload; |
| } __attribute__((packed)); |
| |
| void dump_blk_headers(char *ptr) { |
| int i; |
| struct seemp_logk_blk *temp; |
| |
| for (i = 0; i < (FOUR_MB / 256); i++) { |
| temp = (struct seemp_logk_blk *)ptr; |
| |
| ptr += 256; |
| } |
| } |
| |
| void print_maps(int time) { |
| char cmd[] = "/proc/%d/maps"; |
| char cmd2[sizeof("/proc/-2147483648/maps")]; |
| FILE *fp; |
| size_t nread; |
| char buf[1024]; |
| |
| snprintf(cmd2, sizeof(cmd2)-1, cmd, getpid()); |
| |
| fp = fopen(cmd2, "r"); |
| if (fp == NULL) { |
| exit(-1); |
| } |
| |
| while ((nread = fread(buf, 1, sizeof(buf), fp)) > 0) |
| fwrite(buf, 1, nread, stdout); |
| |
| fclose(fp); |
| sleep(time); |
| } |
| |
| void reserve_rdblks(int fd) { |
| struct read_range rrange; |
| ioctl(fd, SEEMP_CMD_RESERVE_RDBLKS, &rrange); |
| } |
| |
| unsigned int get_ringsz(int fd) { |
| unsigned int ringsz; |
| ioctl(fd, SEEMP_CMD_GET_RINGSZ, &ringsz); |
| return ringsz; |
| } |
| |
| unsigned int get_blksz(int fd) { |
| unsigned int blksz; |
| ioctl(fd, SEEMP_CMD_GET_BLKSZ, &blksz); |
| return blksz; |
| } |
| |
| void write_to_file(char *ptr) { |
| FILE *dumpfp = fopen("/data/local/tmp/dump", "wb"); |
| int i; |
| |
| if (dumpfp == NULL) { |
| exit(-1); |
| } |
| |
| fwrite(ptr, 1, FOUR_MB, dumpfp); |
| fclose(dumpfp); |
| } |
| |
| void write_to_dev(int fd) { |
| char ts[] = "IIIIIIIIIIIIIIIIIIII"; |
| char appname[] = "JJJJJJJJJJJJJJJJ"; |
| char msg[] = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; |
| |
| struct seemp_logk_blk block; |
| |
| block.status = 0xff; |
| block.len = 0x4242; |
| block.version = 'C'; |
| block.pid = 0x44444444; |
| block.uid = 0x45454545; |
| block.tid = 0x46464646; |
| block.sec = 0x47474747; |
| block.nsec = 0x48484848; |
| strcpy(block.ts, ts); |
| strcpy(block.appname, appname); |
| block.payload.api_id = 0x51515151; |
| strcpy(block.payload.msg, msg); |
| } |
| |
| void do_mapping(void **ptr, int fd) { |
| *ptr = mmap(NULL, |
| FOUR_MB, |
| 0x7, |
| MAP_SHARED, |
| fd, |
| 0); |
| if (*ptr == MAP_FAILED) { |
| close(fd); |
| exit(-1); |
| } |
| } |
| |
| void spam_mapped_region(char *ptr, int offset, int size) { |
| int i; |
| for (i = offset; i < size; i++) |
| *(ptr + i) = 'A'; |
| } |
| |
| void start_printk(int fd) { |
| ioctl(fd, SEEMP_CMD_DEBUG_START, NULL); |
| } |
| |
| void stop_printk(int fd) { |
| ioctl(fd, SEEMP_CMD_DEBUG_STOP, NULL); |
| } |
| |
| int main() { |
| int fd; |
| void *ptr; |
| int i; |
| |
| fd = open(DEVICE, O_RDWR); |
| if (fd == -1) { |
| exit(-1); |
| } |
| |
| start_printk(fd); |
| |
| do_mapping(&ptr, fd); |
| |
| for (i = 0; i < (FOUR_MB / 256); i++) |
| write_to_dev(fd); |
| |
| dump_blk_headers(ptr); |
| print_maps(5); |
| |
| write_to_file(ptr); |
| |
| stop_printk(fd); |
| |
| close(fd); |
| munmap(ptr, FOUR_MB); |
| |
| return 0; |
| } |
| |