Esempio n. 1
0
/**
 * @internal
 * @brief Retrieves the volume label.
 * @param[in] hRoot handle to the
 * root directory.
 * @param[out] pointer to the structure
 * receiving the volume label.
 */
static void get_volume_label(HANDLE hRoot,winx_volume_information *v)
{
    FILE_FS_VOLUME_INFORMATION *ffvi;
    int buffer_size;
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS status;
    
    /* reset label */
    v->label[0] = 0;
    
    /* allocate memory */
    buffer_size = (sizeof(FILE_FS_VOLUME_INFORMATION) - sizeof(wchar_t)) + (MAX_PATH + 1) * sizeof(wchar_t);
    ffvi = winx_malloc(buffer_size);
    
    /* try to get actual label */
    RtlZeroMemory(ffvi,buffer_size);
    status = NtQueryVolumeInformationFile(hRoot,&IoStatusBlock,ffvi,
                buffer_size,FileFsVolumeInformation);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot get volume label of drive %c:",
            v->volume_letter);
        winx_free(ffvi);
        return;
    }
    wcsncpy(v->label,ffvi->VolumeLabel,MAX_PATH);
    v->label[MAX_PATH] = 0;
    winx_free(ffvi);
}
Esempio n. 2
0
/**
 * @brief Queries an environment variable.
 * @param[in] name the environment variable name.
 * @return The value of the environment variable.
 * NULL indicates failure.
 * @note The returned string should be freed
 * by the winx_free call after its use.
 */
wchar_t *winx_getenv(wchar_t *name)
{
    wchar_t *value;
    UNICODE_STRING n, v;
    NTSTATUS status;
    
    DbgCheck1(name,NULL);
    
    value = winx_malloc(MAX_ENV_VALUE_LENGTH * sizeof(wchar_t));

    RtlInitUnicodeString(&n,name);
    v.Buffer = value;
    v.Length = 0;
    v.MaximumLength = MAX_ENV_VALUE_LENGTH * sizeof(wchar_t);
    status = RtlQueryEnvironmentVariable_U(NULL,&n,&v);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot query %ws",name);
        winx_free(value);
        return NULL;
    }
    if(value[0] == 0){
        winx_free(value);
        return NULL;
    }
    return value;
}
Esempio n. 3
0
/**
 * @internal
 * @brief Saves the list of boot
 * execute programs to registry.
 * @return Zero for success,
 * negative value otherwise.
 */
static int save_boot_exec_list(struct cmd *list)
{
    struct cmd *c;
    int length = 1;
    wchar_t *commands, *p;
    NTSTATUS status;
    
    for(c = list; c; c = c->next){
        if(c->cmd[0]) length += (int)wcslen(c->cmd) + 1;
        if(c->next == list) break;
    }
    commands = winx_malloc(length * sizeof(wchar_t));
    memset(commands,0,length * sizeof(wchar_t));
    for(c = list, p = commands; c; c = c->next){
        if(c->cmd[0]){
            wcscpy(p,c->cmd);
            p += wcslen(c->cmd) + 1;
        }
        if(c->next == list) break;
    }
    
    status = RtlWriteRegistryValue(RTL_REGISTRY_CONTROL,
        L"Session Manager",L"BootExecute",REG_MULTI_SZ,
        commands,length * sizeof(wchar_t));
    winx_free(commands);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot save list of boot execute commands");
        return (-1);
    }
    return 0;
}
Esempio n. 4
0
/**
 * @brief Terminates the current thread.
 * @param[in] status the exit status.
 * @note This routine causes a small memory leak,
 * because it doesn't deallocate the initial stack.
 * On the other hand, such deallocation seems to be
 * not easy and even if we'll find a proper solution
 * for, let's say XP, we cannot guarantee its work
 * on other systems.
 */
void winx_exit_thread(NTSTATUS status)
{
    NTSTATUS s = ZwTerminateThread(NtCurrentThread(),status);
    if(!NT_SUCCESS(s)){
        strace(s,"cannot terminate thread");
    }
}
Esempio n. 5
0
int     main(int argc, char **argv)
{
  pid_t                         pid;

  if (argc < 2)
    {
      printf("Usage: ./strace [-p] <pid | executable>\n");
      return (EXIT_SUCCESS);
    }
  if (is_attach(argc, argv) == -1)
    {
      if ((pid = fork()) == 0)
	{
	  xptrace(PTRACE_TRACEME, 0, NULL, 0);
	  xexecvp(argv[1], &argv[1]);
	}
      else if (pid != -1)
	{
	  print_execve_arg(argc, argv);
	  strace(pid, 1);
	}
      else
	fprintf(stderr, "Error: fork failed\n");
    }
  return (0);
}
Esempio n. 6
0
/**
 * @brief Gets the fully quallified path of the current module.
 * @details This routine is the native equivalent of GetModuleFileName.
 * @note The returned string should be freed by the winx_free call after its use.
 */
wchar_t *winx_get_module_filename(void)
{
    PROCESS_BASIC_INFORMATION pi;
    NTSTATUS status;
    UNICODE_STRING *us;
    wchar_t *path;
    int size;
    
    RtlZeroMemory(&pi,sizeof(pi));
    status = NtQueryInformationProcess(NtCurrentProcess(),
                    ProcessBasicInformation,&pi,
                    sizeof(pi),NULL);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot query basic process information");
        return NULL;
    }
    
    us = &pi.PebBaseAddress->ProcessParameters->ImagePathName;
    size = us->MaximumLength + sizeof(wchar_t);
    path = winx_tmalloc(size);
    if(path == NULL){
        mtrace();
        return NULL;
    }
    
    memset(path,0,size);
    memcpy(path,us->Buffer,us->Length);
    return path;
}
Esempio n. 7
0
long syscall_SYS_fcntl(int fd, int cmd, ... /* arg */ )
{
  va_list va;
  va_start(va, cmd);
  auto ret = strace(sys_fcntl, "fcntl", fd, cmd, va);
  va_end(va);
  return ret;
}
Esempio n. 8
0
void watchAndStraceZygote()
{
    system("rm -f %s", ZYGOTE_SYSCALL_TRACE_FILE);
    int pid = findZygotePid();

    char *straceOutput = ZYGOTE_SYSCALL_TRACE_FILE;
    strace(pid, straceOutput);
    //printf("zygote pid is %d\n", pid);
}
Esempio n. 9
0
/**
 * @brief Enables a user privilege for the current process.
 * @param[in] luid the identifier of the requested privilege, 
 * ntndk.h file contains definitions of various privileges.
 * @return Zero for success, negative value otherwise.
 * @par Example:
 * @code
 * winx_enable_privilege(SE_SHUTDOWN_PRIVILEGE);
 * @endcode
 */
int winx_enable_privilege(unsigned long luid)
{
    NTSTATUS status;
    SIZE_T WasEnabled; /* boolean value receiving the previous state */
    
    status = RtlAdjustPrivilege((SIZE_T)luid, TRUE, FALSE, &WasEnabled);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot enable privilege %x",(UINT)luid);
        return (-1);
    }
    return 0;
}
Esempio n. 10
0
/**
 * @brief Releases a mutex.
 * @param[in] h the mutex handle.
 * @return Zero for success, 
 * negative value otherwise.
 */
int winx_release_mutex(HANDLE h)
{
    NTSTATUS status;
    
    DbgCheck1(h,-1);
    
    status = NtReleaseMutant(h,NULL);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot release mutex");
        return (-1);
    }
    return 0;
}
Esempio n. 11
0
/**
 * @brief Creates a thread and starts them.
 * @param[in] start_addr the starting address of the thread.
 * @param[in] parameter pointer to the data passed to the thread routine.
 * @return Zero for success, negative value otherwise.
 * @note Look at the following example for the thread function prototype.
 * @par Example:
 * @code
 * DWORD WINAPI thread_proc(LPVOID parameter)
 * {
 *     // do something
 *     winx_exit_thread(0);
 *     return 0;
 * }
 * winx_create_thread(thread_proc,NULL);
 * @endcode
 */
int winx_create_thread(PTHREAD_START_ROUTINE start_addr,PVOID parameter)
{
    NTSTATUS status;
    HANDLE hThread;

    DbgCheck1(start_addr,-1);

    status = RtlCreateUserThread(NtCurrentProcess(),NULL,
                    0,0,0,0,start_addr,parameter,&hThread,NULL);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot create thread");
        return (-1);
    }
    NtCloseSafe(hThread);
    return 0;
}
Esempio n. 12
0
/**
 * @internal
 * @brief Retrieves the list of
 * registered boot execute programs.
 * @return Zero for success,
 * negative value otherwise.
 */
static int get_boot_exec_list(struct cmd **list)
{
    NTSTATUS status;
    RTL_QUERY_REGISTRY_TABLE qt[] = {
        {query_routine, 0, L"BootExecute", NULL, REG_SZ, L"",  0},
        {NULL,          0, NULL,           NULL, 0,      NULL, 0}
    };
    
    status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
        L"Session Manager",qt,(PVOID)list,NULL);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot get list of boot execute commands");
        return (-1);
    }
    return 0;
}
Esempio n. 13
0
/**
 * @internal
 * @brief Retrieves the drive geometry.
 * @param[in] hRoot handle to the
 * root directory.
 * @param[out] pointer to the structure
 * receiving the drive geometry.
 * @return Zero for success, negative
 * value otherwise.
 */
static int get_drive_geometry(HANDLE hRoot,winx_volume_information *v)
{
    FILE_FS_SIZE_INFORMATION ffs;
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS status;
    WINX_FILE *f;
    DISK_GEOMETRY dg;
    char buffer[32];
    
    /* get drive geometry */
    RtlZeroMemory(&ffs,sizeof(FILE_FS_SIZE_INFORMATION));
    status = NtQueryVolumeInformationFile(hRoot,&IoStatusBlock,&ffs,
                sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot get geometry of drive %c:",v->volume_letter);
        return (-1);
    }
    
    /* fill all geometry related fields of the output structure */
    v->total_bytes = (ULONGLONG)ffs.TotalAllocationUnits.QuadPart * \
        ffs.SectorsPerAllocationUnit * ffs.BytesPerSector;
    v->free_bytes = (ULONGLONG)ffs.AvailableAllocationUnits.QuadPart * \
        ffs.SectorsPerAllocationUnit * ffs.BytesPerSector;
    v->total_clusters = (ULONGLONG)ffs.TotalAllocationUnits.QuadPart;
    v->bytes_per_cluster = ffs.SectorsPerAllocationUnit * ffs.BytesPerSector;
    v->sectors_per_cluster = ffs.SectorsPerAllocationUnit;
    v->bytes_per_sector = ffs.BytesPerSector;
    
    /* optional: get device capacity */
    v->device_capacity = 0;
    f = winx_vopen(v->volume_letter);
    if(f != NULL){
        if(winx_ioctl(f,IOCTL_DISK_GET_DRIVE_GEOMETRY,
          "get_drive_geometry: device geometry request",NULL,0,
          &dg,sizeof(dg),NULL) >= 0){
            v->device_capacity = dg.Cylinders.QuadPart * \
                dg.TracksPerCylinder * dg.SectorsPerTrack * dg.BytesPerSector;
            winx_bytes_to_hr(v->device_capacity,1,buffer,sizeof(buffer));
            itrace("%c: device capacity = %s",v->volume_letter,buffer);
        }
        winx_fclose(f);
    }
    return 0;
}
Esempio n. 14
0
/**
 * @brief Opens a named mutex.
 * @param[in] name the mutex name.
 * @param[out] phandle pointer to the mutex handle.
 * @return Zero for success, negative value otherwise.
 * @par Example:
 * @code
 * HANDLE h;
 * winx_open_mutex(L"\\BaseNamedObjects\\ultradefrag_mutex",&h);
 * @endcode
 */
int winx_open_mutex(wchar_t *name,HANDLE *phandle)
{
    UNICODE_STRING us;
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;

    DbgCheck2(name,phandle,-1);
    *phandle = NULL;

    RtlInitUnicodeString(&us,name);
    InitializeObjectAttributes(&oa,&us,0,NULL,NULL);
    status = NtOpenMutant(phandle,MUTEX_ALL_ACCESS,&oa);
    if(!NT_SUCCESS(status)){
        *phandle = NULL;
        strace(status,"cannot open %ws",name);
        return (-1);
    }
    return 0;
}
Esempio n. 15
0
void Tracer::trace(TraceLevel level, const char* method, const char* message, ...) const
{
    // immediately return if the current set tracelevel is higher
    if (m_tracelevel > level) {
        return;
    }

    ///@todo with qt4 the follwing code can be used:
    /*
    va_list ap;
    va_start(ap, message);
    QString str;
    str.vsprintf(message, ap);
    va_end(ap);

    strace(level, method) << str << endl;
    */

    va_list ap;

    int maxLength = 1024;
    int result = maxLength;
    char* str;
    while (result >= maxLength) {
        va_start(ap, message);
        str = (char*)malloc(maxLength);
        result = vsnprintf(str, maxLength-1, message, ap);
        va_end(ap);

        if (result >= maxLength) {
            delete str;
            maxLength = 2 * maxLength;
            result = maxLength;
        }
    }

    strace(level, method) << str << endl;
    delete str;
}
Esempio n. 16
0
/**
 * @internal
 * @brief Opens root directory of the volume.
 * @param[in] volume_letter the volume letter.
 * @return File handle, NULL indicates failure.
 */
static HANDLE OpenRootDirectory(unsigned char volume_letter)
{
    wchar_t rootpath[] = L"\\??\\A:\\";
    HANDLE hRoot;
    NTSTATUS status;
    UNICODE_STRING us;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;

    rootpath[4] = (wchar_t)winx_toupper(volume_letter);
    RtlInitUnicodeString(&us,rootpath);
    InitializeObjectAttributes(&ObjectAttributes,&us,
                   FILE_READ_ATTRIBUTES,NULL,NULL);
    status = NtCreateFile(&hRoot,FILE_GENERIC_READ,
                &ObjectAttributes,&IoStatusBlock,NULL,0,
                FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN,0,
                NULL,0);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot open %ls",rootpath);
        return NULL;
    }
    return hRoot;
}
Esempio n. 17
0
/**
 * @brief Creates a named mutex.
 * @param[in] name the mutex name.
 * @param[out] phandle pointer to the mutex handle.
 * @return Zero for success, negative value otherwise.
 * @par Example:
 * @code
 * HANDLE h;
 * winx_create_mutex(L"\\BaseNamedObjects\\ultradefrag_mutex",&h);
 * @endcode
 */
int winx_create_mutex(wchar_t *name,HANDLE *phandle)
{
    UNICODE_STRING us;
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;

    DbgCheck2(name,phandle,-1);
    *phandle = NULL;

    RtlInitUnicodeString(&us,name);
    InitializeObjectAttributes(&oa,&us,0,NULL,NULL);
    status = NtCreateMutant(phandle,MUTEX_ALL_ACCESS,&oa,0);
    if(status == STATUS_OBJECT_NAME_COLLISION){
        itrace("%ws already exists",name);
        status = NtOpenMutant(phandle,MUTEX_ALL_ACCESS,&oa);
    }
    if(!NT_SUCCESS(status)){
        *phandle = NULL;
        strace(status,"cannot create/open %ws",name);
        return (-1);
    }
    return 0;
}
Esempio n. 18
0
/**
 * @brief Sets an environment variable.
 * @param[in] name the environment variable name.
 * @param[in] value the null-terminated value string.
 * NULL pointer causes a variable deletion.
 * @return Zero for success, negative value otherwise.
 * @note value buffer size must not exceed 32767 characters,
 * including terminal zero, as mentioned in MSDN. This is
 * because unsigned short data type can hold numbers
 * less than or equal to 32767.
 */
int winx_setenv(wchar_t *name, wchar_t *value)
{
    UNICODE_STRING n, v;
    NTSTATUS status;

    DbgCheck1(name,-1);

    RtlInitUnicodeString(&n,name);
    if(value){
        if(value[0]){
            RtlInitUnicodeString(&v,value);
            status = RtlSetEnvironmentVariable(NULL,&n,&v);
        } else {
            status = RtlSetEnvironmentVariable(NULL,&n,NULL);
        }
    } else {
        status = RtlSetEnvironmentVariable(NULL,&n,NULL);
    }
    if(!NT_SUCCESS(status)){
        strace(status,"cannot set %ws",name);
        return (-1);
    }
    return 0;
}
Esempio n. 19
0
/**
 * @internal
 * @brief Retrieves the name of the file system.
 * @param[in] hRoot handle to the root directory.
 * @param[out] pointer to the structure receiving
 * the filesystem name.
 * @return Zero for success, negative value otherwise.
 * @note We could analyze the first sector of the 
 * partition directly, but this method is not so swift
 * as it accesses the disk physically.
 */
static int get_filesystem_name(HANDLE hRoot,winx_volume_information *v)
{
    FILE_FS_ATTRIBUTE_INFORMATION *pfa;
    int fs_attr_info_size;
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS status;
    wchar_t fs_name[MAX_FS_NAME_LENGTH + 1];
    int length;

    fs_attr_info_size = MAX_PATH * sizeof(WCHAR) + sizeof(FILE_FS_ATTRIBUTE_INFORMATION);
    pfa = winx_malloc(fs_attr_info_size);
    
    RtlZeroMemory(pfa,fs_attr_info_size);
    status = NtQueryVolumeInformationFile(hRoot,&IoStatusBlock,pfa,
                fs_attr_info_size,FileFsAttributeInformation);
    if(!NT_SUCCESS(status)){
        strace(status,"cannot get file system name of drive %c:",v->volume_letter);
        winx_free(pfa);
        return (-1);
    }
    
    /*
    * pfa->FileSystemName.Buffer may be not NULL terminated
    * (theoretically), so name extraction is more tricky
    * than it should be.
    */
    length = min(MAX_FS_NAME_LENGTH,pfa->FileSystemNameLength / sizeof(wchar_t));
    wcsncpy(fs_name,pfa->FileSystemName,length);
    fs_name[length] = 0;
    _snprintf(v->fs_name,MAX_FS_NAME_LENGTH,"%ws",fs_name);
    v->fs_name[MAX_FS_NAME_LENGTH] = 0;

    /* cleanup */
    winx_free(pfa);
    return 0;
}
Esempio n. 20
0
long syscall_SYS_fchown(int fd, uid_t owner, gid_t group)
{
  return strace(sys_fchown, "fchown", fd, owner, group);
}
Esempio n. 21
0
void syscall_SYS_exit(int status) {
  strace(sys_exit, "exit", status);
}
Esempio n. 22
0
long syscall_SYS_mremap(void *old_address, size_t old_size,
                        size_t new_size, int flags, void *new_address)
{
  return strace(sys_mremap, "mremap", old_address, old_size, new_size, flags, new_address);
}
Esempio n. 23
0
ssize_t socketcall_sendto(int sockfd, const void *buf, size_t len, int flags,
                          const struct sockaddr *dest_addr, socklen_t addrlen)
{
  return strace(sock_sendto, "sendto", sockfd, buf, len, flags, dest_addr, addrlen);
}
Esempio n. 24
0
long syscall_SYS_setrlimit(int resource,
               const struct rlimit* rlim)
{
  return strace(sys_setrlimit, "setrlimit", resource, rlim);
}
Esempio n. 25
0
long socketcall_shutdown(int sockfd, int how)
{
  return strace(sock_shutdown, "shutdown", sockfd, how);
}
Esempio n. 26
0
long socketcall_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
  return strace(sock_accept, "accept", sockfd, addr, addrlen);
}
Esempio n. 27
0
long socketcall_bind(int sockfd, const struct sockaddr *addr,
                     socklen_t addrlen)
{
  return strace(sock_bind, "bind", sockfd, addr, addrlen);
}
Esempio n. 28
0
ssize_t socketcall_recvfrom(int sockfd, void *buf, size_t len, int flags,
                            struct sockaddr *src_addr, socklen_t *addrlen)
{
  return strace(sock_recvfrom, "recvfrom", sockfd, buf, len, flags, src_addr, addrlen);
}
Esempio n. 29
0
long socketcall_listen(int sockfd, int backlog)
{
  return strace(sock_listen, "listen", sockfd, backlog);
}
Esempio n. 30
0
long socketcall_sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
  return strace(sock_sendmsg, "sendmsg", sockfd, msg, flags);
}