Fix yr_rules_scan_proc (#785)

* Add simple test for yr_rules_scan_proc

* Fix process scanning on Linux/i386

- Configure large file support (-D_FILE_OFFSET_BITS=64). Enough for
  scanning 32bit processes.

- Change data types so that they can hold large offsets. Required for
  scanning 64bit processes such as the shell that is spawned from
  test-rules on the Travis CI host.

Closes #784

* Do not fail process scan test if attaching failed.

Apparently, MacOSX rules for task_for_pid() have been changed over
time such that a user is not necessarily allowed to read memory from
his own processes.
This commit is contained in:
Hilko Bengen
2017-11-05 20:19:18 +01:00
committed by Victor M. Alvarez
parent 7c170036ba
commit dfd6f7b5f3
4 changed files with 75 additions and 4 deletions
+4
View File
@@ -19,6 +19,7 @@ AC_PROG_CC
AM_PROG_CC_C_O
AM_PROG_LEX
AC_PROG_YACC
AC_SYS_LARGEFILE
LT_INIT
AC_PROG_LIBTOOL
@@ -217,6 +218,9 @@ AM_CONDITIONAL([USE_WINDOWS_PROC], [test x$proc_interface = xwindows ])
AM_CONDITIONAL([USE_LINUX_PROC], [test x$proc_interface = xlinux ])
AM_CONDITIONAL([USE_MACH_PROC], [test x$proc_interface = xmach ])
AM_CONDITIONAL([USE_NO_PROC], [test x$proc_interface = xnone ])
AS_IF(
[test x$proc_interface != xnone],[AC_DEFINE([HAVE_SCAN_PROC_IMPL],[1])],
[test x$proc_interface = xnone],[AC_DEFINE([HAVE_SCAN_PROC_IMPL],[0])])
AC_SUBST([PC_REQUIRES_PRIVATE])
AC_SUBST([PC_LIBS_PRIVATE])
+2 -2
View File
@@ -408,8 +408,8 @@ typedef struct _YR_MEMORY_BLOCK* (*YR_MEMORY_BLOCK_ITERATOR_FUNC)(
typedef struct _YR_MEMORY_BLOCK
{
size_t size;
size_t base;
uint64_t size;
uint64_t base;
void* context;
+3 -2
View File
@@ -39,6 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#include <fcntl.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
@@ -189,11 +190,11 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info;
char buffer[256];
size_t begin, end;
uint64_t begin, end;
if (fgets(buffer, sizeof(buffer), proc_info->maps) != NULL)
{
sscanf(buffer, "%zx-%zx", &begin, &end);
sscanf(buffer, "%"SCNx64"-%"SCNx64, &begin, &end);
context->current_block.base = begin;
context->current_block.size = end - begin;
+66
View File
@@ -27,6 +27,10 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <yara.h>
#include "blob.h"
#include "util.h"
@@ -1694,6 +1698,64 @@ void test_include_files()
}
void test_process_scan()
{
int pid = fork();
int status = 0;
int matches = 0;
YR_RULES* rules;
int rc1, rc2;
if (pid == 0)
{
/* The string should appear somewhere in the shell's process space. */
if (execl("/bin/sh", "sh", "-c", "VAR='Hello, world!'; sleep 5", NULL) == -1)
exit(1);
}
assert(pid > 0);
/* Give child process time to initialize */
sleep(1);
assert( compile_rule("\
rule test {\
strings:\
$a = { 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 }\
condition:\
all of them\
}", &rules) == ERROR_SUCCESS);
rc1 = yr_rules_scan_proc(rules, pid, 0, count_matches, &matches, 0);
rc2 = waitpid(pid, &status, 0);
if (rc2 == -1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}
if (status != 0)
{
fprintf(stderr, "Scanned process exited with status %d\n", status);
exit(EXIT_FAILURE);
}
switch (rc1) {
case ERROR_SUCCESS:
if (matches == 0)
{
fputs("Found no matches", stderr);
exit(EXIT_FAILURE);
}
break;
case ERROR_COULD_NOT_ATTACH_TO_PROCESS:
fputs("Could not attach to process, ignoring this error", stderr);
break;
default:
fprintf(stderr, "yr_rules_scan_proc: Got unexpected error %d\n", rc1);
exit(EXIT_FAILURE);
}
}
int main(int argc, char** argv)
{
yr_initialize();
@@ -1731,6 +1793,10 @@ int main(int argc, char** argv)
test_entrypoint();
test_global_rules();
#if HAVE_SCAN_PROC_IMPL == 1
test_process_scan();
#endif
#if defined(HASH_MODULE)
test_hash_module();
#endif