У меня есть небольшой код C, который сбрасывает память процесса, а затем пытается привязать REGEX к строке. Все идет хорошо, если я хочу сбрасывать процесс, но REGEX терпит неудачу, или я неправильно искал буфер памяти. Есть идеи?Linux C область памяти процесса сброса и поиск строки проблемы
#define _LARGEFILE64_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <fcntl.h>
#include <regex.h>
void dump_region(int fd, off64_t start, off64_t end)
{
char buf[4096];
int a, i;
regex_t re;
regmatch_t pm;
a = regcomp(&re, "([0-9]{10,20})", REG_EXTENDED);
if(a!=0)
printf(" -> Error: Invalid Regex");
lseek64(fd, start, SEEK_SET);
while(start < end) {
int rd;
rd = read(fd, buf, 4096);
//write(STDOUT_FILENO, buf, rd); // HERE dumping is OK
a = regexec(&re, &buf[0], 1, &pm, REG_EXTENDED); // something I do wrong here
if(a==0) {
for(i = pm.rm_so; i < pm.rm_eo; i++)
printf("%c", buf[i]);
printf("\n");
}
start += 4096;
}
}
int main(int argc, char *argv[])
{
FILE *maps;
int mem;
pid_t pid;
char path[BUFSIZ];
if(argc < 2) {
fprintf(stderr, "usage: %s pid\n", argv[0]);
return EXIT_FAILURE;
}
pid = strtol(argv[1], NULL, 10);
if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("ptrace");
return EXIT_FAILURE;
}
snprintf(path, sizeof(path), "/proc/%d/maps", pid);
maps = fopen(path, "r");
snprintf(path, sizeof(path), "/proc/%d/mem", pid);
mem = open(path, O_RDONLY);
if(maps && mem != -1) {
char buf[BUFSIZ + 1];
while(fgets(buf, BUFSIZ, maps)) {
off64_t start, end;
sscanf(buf, "%llx-%llx", &start, &end);
dump_region(mem, start, end);
}
}
ptrace(PTRACE_DETACH, pid, NULL, NULL);
if(mem != -1)
close(mem);
if(maps)
fclose(maps);
return EXIT_SUCCESS;
}
EDIT:
Пробовал другой вариант, еще что-то пойдет не так или что-то я просто скучаю ...
#define _LARGEFILE64_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <fcntl.h>
#include <regex.h>
void dump_region(int fd, off64_t start, off64_t end)
{
char buf[4096];
int status,i;
int cflags = REG_EXTENDED;
regmatch_t pmatch[1];
const size_t nmatch=1;
regex_t reg;
const char *pattern="([0-9]{10,20})";
regcomp(®, pattern, cflags);
lseek64(fd, start, SEEK_SET);
while(start < end) {
int rd;
rd = read(fd, buf, sizeof buf - 1);
if(rd > 0)
{
buf[rd] = '\0';
status = regexec(®, buf, nmatch, pmatch, 0);
if(status == REG_NOMATCH)
printf("No Match\n");
else if(status == 0){
printf("Match:\n");
for (i=pmatch[0].rm_so; i<pmatch[0].rm_eo; ++i) {
putchar(buf[i]);
}
printf("\n");
}
regfree(®);
return;
}
start += 4096;
}
}
int main(int argc, char *argv[])
{
FILE *maps;
int mem;
pid_t pid;
char path[BUFSIZ];
if(argc < 2) {
fprintf(stderr, "usage: %s pid\n", argv[0]);
return EXIT_FAILURE;
}
pid = strtol(argv[1], NULL, 10);
if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("ptrace");
return EXIT_FAILURE;
}
snprintf(path, sizeof(path), "/proc/%d/maps", pid);
maps = fopen(path, "r");
snprintf(path, sizeof(path), "/proc/%d/mem", pid);
mem = open(path, O_RDONLY);
if(maps && mem != -1) {
char buf[BUFSIZ + 1];
while(fgets(buf, BUFSIZ, maps)) {
off64_t start, end;
sscanf(buf, "%llx-%llx", &start, &end);
dump_region(mem, start, end);
}
}
ptrace(PTRACE_DETACH, pid, NULL, NULL);
if(mem != -1)
close(mem);
if(maps)
fclose(maps);
return EXIT_SUCCESS;
}
Любая помощь? Идея?
ОБНОВЛЕНИЕ. Кажется, что вторая версия работает частично, но примерно от 1193
совпадений, которые я получаю с egrep
из файла сбрасываемой памяти, я получаю только два кода с моим кодом. Есть идеи?
Я не знаю много о regexp в C, но не должен '& buf [0]' быть просто '& buf', чтобы дать ссылку на начало буфера? – Aif
Дамп в файл, запустите 'файл строк | egrep 'ваше регулярное выражение'. Это нашло? Если это так, регулярное выражение является правильным, а бит, который вам не хватает, - это извлечение c-строки (как предложено в ответе от разговора) – Useless
Да, я сделал это, использовал тот же код, но сбрасывал в файл, а затем использовал строки с точным REGEX и обнаружил много матчей. – bsteo