/* Does a memscan, then goes from big endian to native endian on the * destination. */ static inline const void* swapped_memscan(void* dest, const void* src, size_t n) { const void* ret = memscan(dest, src, n); return be2ne(dest, n), ret; }
/* Read the environment variable of current process specified by @key. */ int cfs_get_environ(const char *key, char *value, int *val_len) { struct mm_struct *mm; char *buffer; int buf_len = PAGE_CACHE_SIZE; int key_len = strlen(key); unsigned long addr; int rc; ENTRY; buffer = kmalloc(buf_len, GFP_USER); if (!buffer) RETURN(-ENOMEM); mm = get_task_mm(current); if (!mm) { kfree(buffer); RETURN(-EINVAL); } /* Avoid deadlocks on mmap_sem if called from sys_mmap_pgoff(), * which is already holding mmap_sem for writes. If some other * thread gets the write lock in the meantime, this thread will * block, but at least it won't deadlock on itself. LU-1735 */ if (down_read_trylock(&mm->mmap_sem) == 0) { kfree(buffer); return -EDEADLK; } up_read(&mm->mmap_sem); addr = mm->env_start; while (addr < mm->env_end) { int this_len, retval, scan_len; char *env_start, *env_end; memset(buffer, 0, buf_len); this_len = min_t(int, mm->env_end - addr, buf_len); retval = cfs_access_process_vm(current, addr, buffer, this_len, 0); if (retval != this_len) break; addr += retval; /* Parse the buffer to find out the specified key/value pair. * The "key=value" entries are separated by '\0'. */ env_start = buffer; scan_len = this_len; while (scan_len) { char *entry; int entry_len; env_end = memscan(env_start, '\0', scan_len); LASSERT(env_end >= env_start && env_end <= env_start + scan_len); /* The last entry of this buffer cross the buffer * boundary, reread it in next cycle. */ if (unlikely(env_end - env_start == scan_len)) { /* This entry is too large to fit in buffer */ if (unlikely(scan_len == this_len)) { CERROR("Too long env variable.\n"); GOTO(out, rc = -EINVAL); } addr -= scan_len; break; } entry = env_start; entry_len = env_end - env_start; /* Key length + length of '=' */ if (entry_len > key_len + 1 && !memcmp(entry, key, key_len)) { entry += key_len + 1; entry_len -= key_len + 1; /* The 'value' buffer passed in is too small.*/ if (entry_len >= *val_len) GOTO(out, rc = -EOVERFLOW); memcpy(value, entry, entry_len); *val_len = entry_len; GOTO(out, rc = 0); } scan_len -= (env_end - env_start + 1); env_start = env_end + 1; } } GOTO(out, rc = -ENOENT); out: mmput(mm); kfree((void *)buffer); return rc; }
/* Read the environment variable of current process specified by @key. */ int cfs_get_environ(const char *key, char *value, int *val_len) { struct mm_struct *mm; char *buffer; int buf_len = PAGE_CACHE_SIZE; int key_len = strlen(key); unsigned long addr; int rc; bool skip = false; ENTRY; buffer = kmalloc(buf_len, GFP_USER); if (!buffer) RETURN(-ENOMEM); mm = get_task_mm(current); if (!mm) { kfree(buffer); RETURN(-EINVAL); } addr = mm->env_start; while (addr < mm->env_end) { int this_len, retval, scan_len; char *env_start, *env_end; memset(buffer, 0, buf_len); this_len = min_t(int, mm->env_end - addr, buf_len); retval = cfs_access_process_vm(current, mm, addr, buffer, this_len, 0); if (retval < 0) GOTO(out, rc = retval); else if (retval != this_len) break; addr += retval; /* Parse the buffer to find out the specified key/value pair. * The "key=value" entries are separated by '\0'. */ env_start = buffer; scan_len = this_len; while (scan_len) { char *entry; int entry_len; env_end = memscan(env_start, '\0', scan_len); LASSERT(env_end >= env_start && env_end <= env_start + scan_len); /* The last entry of this buffer cross the buffer * boundary, reread it in next cycle. */ if (unlikely(env_end - env_start == scan_len)) { /* Just skip the entry larger than page size, * it can't be jobID env variable. */ if (unlikely(scan_len == this_len)) skip = true; else addr -= scan_len; break; } else if (unlikely(skip)) { skip = false; goto skip; } entry = env_start; entry_len = env_end - env_start; /* Key length + length of '=' */ if (entry_len > key_len + 1 && !memcmp(entry, key, key_len)) { entry += key_len + 1; entry_len -= key_len + 1; /* The 'value' buffer passed in is too small.*/ if (entry_len >= *val_len) GOTO(out, rc = -EOVERFLOW); memcpy(value, entry, entry_len); *val_len = entry_len; GOTO(out, rc = 0); } skip: scan_len -= (env_end - env_start + 1); env_start = env_end + 1; } } GOTO(out, rc = -ENOENT); out: mmput(mm); kfree((void *)buffer); return rc; }
// main :] int main(int argc, char** argv) { pmempattern list, current; BYTE pattern1[]={ 0x5E,0x81,0xC6,0xFB,0x01,0x00,0x00,0x8D, 0xBD,0x84,0xF0,0xFF,0xFF,0x0F,0xB7,0x06, 0x0F,0xB7,0x4E,0x02,0x83,0xC6,0x04,0x03, 0xC7,0x51,0x51,0x56,0x50,0xFF,0x95,0x2D, 0xF1,0xFF,0xFF,0x59,0x03,0xF1,0x66,0x83, 0x3E,0x00,0x75,0xE1,0x83,0xC6,0x02,0x89, 0x75,0xF8,0x66,0x83,0x3E,0x00,0x74,0x11, 0x0F,0xB7,0x06,0x0F,0xB7,0x4E,0x02,0x83 }; BYTE pattern2[]={ 0x55,0x8B,0xEC,0x81,0xC4,0x30,0xFA,0xFF, 0xFF,0x8B,0x75,0x08,0x8D,0x86,0xFB,0x03, 0x00,0x00,0x50,0x6A,0x00,0x6A,0x00,0xFF, 0x96,0x85,0x00,0x00,0x00,0x89,0x86,0xC5, 0x08,0x00,0x00,0xFF,0x96,0x89,0x00,0x00, 0x00,0x3D,0xB7,0x00,0x00,0x00,0x75,0x04, 0xC9,0xC2,0x04,0x00,0x56,0x8D,0x86,0x6B, 0x09,0x00,0x00,0x50,0x8D,0x86,0x45,0x01 }; char pattern3[]="\x18\x04\x28\x00SOFTWARE\\Classes\\http\\shell\\open\\command"; char pattern4[]="\x04\x35\x00\x53Software\\Microsoft\\Active Setup\\Installed Components\\"; char pattern5[]="\x0f\x04\x08\x00StubPath"; current = NULL; list = (pmempattern)malloc(sizeof(mempattern)); list->patternId = 1; list->pattern = pattern1; list->patternlen = sizeof(pattern1); list->protect = PAGE_EXECUTE_READWRITE; list->flink = current; current = list; list = (pmempattern)malloc(sizeof(mempattern)); list->patternId = 2; list->pattern = pattern2; list->patternlen = sizeof(pattern2); list->protect = PAGE_EXECUTE_READWRITE; list->flink = current; current = list; list = (pmempattern)malloc(sizeof(mempattern)); list->patternId = 3; list->pattern = pattern3; list->patternlen = sizeof(pattern3)-1; list->protect = PAGE_EXECUTE_READWRITE; list->flink = current; current = list; list = (pmempattern)malloc(sizeof(mempattern)); list->patternId = 4; list->pattern = pattern4; list->patternlen = sizeof(pattern4)-1; list->protect = PAGE_EXECUTE_READWRITE; list->flink = current; current = list; list = (pmempattern)malloc(sizeof(mempattern)); list->patternId = 5; list->pattern = pattern5; list->patternlen = sizeof(pattern5)-1; list->protect = PAGE_EXECUTE_READWRITE; list->flink = current; printf("Find PIVY!\n"); elevate_access_rights(); if(memscan(list)==ERROR_VIRUS_INFECTED) printf("\n\nPIVY found.\n"); current = list; while(current!=NULL) { list = current; current = (pmempattern)(current->flink); free(list); } system("pause"); return 0; }