C++程序  |  215行  |  4.65 KB

/*
 * 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;
}