예제 #1
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// ps_base_address()
//
// search through all loaded modules for a string match and return it's base address.
//
bool ps_base_address (char *module, DWORD *address, DWORD *size)
{
    map <DWORD,t_Debugger_memory*>::const_iterator  it;
    
    dbg.ReBuildMemoryMap();

    // determine the base address of the executable section for the loaded module.
    for (it = dbg.MemoryMap.begin(); it != dbg.MemoryMap.end(); ++it)
    {
        // match the module name.
        if (stricmp(it->second->Name.c_str(), module) != 0)
            continue;

        // ensure we found the correct section.
        if ((it->second->basics.Protect & PAGE_EXECUTE)           ||
            (it->second->basics.Protect & PAGE_EXECUTE_READ)      ||
            (it->second->basics.Protect & PAGE_EXECUTE_READWRITE) ||
            (it->second->basics.Protect & PAGE_EXECUTE_WRITECOPY))
        {
            // module executable section found.
            *address = it->second->address;
            *size    = it->second->basics.RegionSize;
            return true;
        }
    }

    return false;
}
예제 #2
0
int main (int argc, char **argv)
{
    unsigned int cit;
    int          option;
    char         filename[MAX_PATH];
    char         command_line[MAX_PATH];            // win2k max = MAX_PATH, otherwise could be 32k.
    map <DWORD,t_Debugger_memory*>::const_iterator  it;

    // init target char buf.
    memset(target, 0, sizeof(target));

    // Set the debugger's log level. (disable logging)
    dbg.log.set(LOG_SHUTUP);
    dbg.SetGlobalLoglevel(LOG_SHUTUP);

    //
    // do the command line argument thing.
    //

    for (int i = 1; i < argc; i++)
    {
        //
        // attach to a pid.
        //

        if (stricmp(argv[i], "-a") == 0 && i + 1 < argc)
        {
            if (!dbg.attach(atoi(argv[i+1])))
            {
                printf("[ERROR] No process with the ID %u\n", atoi(argv[i+1]));
                return 1;
            }

            // update the target name.
            strncpy(target, argv[i+1], sizeof(target) - 1);

            i++;
        }

        //
        // load a file. (no arguments)
        //

        else if (stricmp(argv[i], "-l") == 0 && i + 1 < argc)
        {
            if (!dbg.load(argv[i+1]))
            {
                printf("[ERROR] Could not load %s\n", argv[i+1]);
                return 1;
            }

            // update the target name.
            strncpy(target, argv[i+1], sizeof(target) - 1);
            
            // cut off the target name at the first dot.
            //char *dot = strchr(target, '.');
            //*dot = 0;

            i++;
        }

        //
        // load a file with arguments.
        //

        else if (stricmp(argv[i], "-la") == 0 && i + 1 < argc)
        {
            _snprintf(command_line, sizeof(command_line), "%s %s", argv[i+1], argv[i+2]);

            if (!dbg.load(argv[i+1], command_line))
            {
                printf("[ERROR] Could not load %s %s\n", argv[i+1], argv[i+2]);
                return 1;
            }

            // update the target name.
            _snprintf(target, sizeof(target), command_line);

            i += 2;
        }

        //
        // select a breakpoint list.
        //

        else if (stricmp(argv[i], "-b") == 0 && i + 1 < argc)
        {
            breakpoint_list = argv[i+1];

            // we open the file now with a global file handle and set the breakpoints after all
            // the modules have been loaded and parsed in the initial breakpoint handler.
            if ((bpl = fopen(breakpoint_list, "r+")) == NULL)
            {
                printf("\n[ERROR] Failed opening breakpoing list: %s\n", breakpoint_list);
                return 1;
            }

            i++;
        }

        //
        // select a starting recorder mode.
        //

        else if (stricmp(argv[i], "-r") == 0 && *target != NULL && i + 1 < argc)
        {
            recorder_mode = atoi(argv[i+1]);

            // create / open recorder file.
            sprintf(filename, "%s.%d", target, recorder_mode);
            recorder = fopen(filename, "a+");

            // create / open the register recorder file if register enumeration hasn't been disabled.
            if (reg_enum_flag)
            {
                sprintf(filename, "%s-regs.%d", target, recorder_mode);
                recorder_regs = fopen(filename, "a+");
            }

            i++;
        }

        //
        // set "one-time" mode. ie: do not restore breakpoints.
        //

        else if (stricmp(argv[i], "--one-time") == 0)
        {
            dbg.one_time = true;
        }

        //
        // disable register enumeration / dereferencing.
        //

        else if (stricmp(argv[i], "--no-regs") == 0)
        {
            reg_enum_flag = false;
        }

        //
        // invalid option.
        //

        else
            ps_usage();
    }

    //
    // command line sanity checking.
    //

    if (*target == NULL)
        ps_usage();

    //
    // print banner and start working.
    //

    printf("\nprocess stalker\n"
           "pedram amini <*****@*****.**>\n"
           "compiled on "__DATE__"\n"
           "target: %s\n\n", target);

    // assign functions to handle breakpoints.
    dbg.set_inital_breakpoint_handler(&initial_break);
    dbg.set_breakpoint_handler(&normal_break);
    dbg.SetCloseRecordFunction(&closer);
    dbg.set_load_dll_handler(&ps_load_dll_callback);

    // assign a function to handle exit event.
    dbg.set_exit_handler(&itsdone);

    dbg.Analysis.StackDelta  = true;
    dbg.Analysis.StackDeltaV = 2048;

    // 
    // application main loop.
    //

    while (!main_terminate)
    {
        dbg.run(1000);

        for (cit = 0; cit < Children.size(); cit++)
                Children[cit]->run(1000);

        if (_kbhit())
        {
            option = getch();

            switch(option)
            {
                // activate a recorder.
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    // convert character option into integer option for recorder mode.
                    option -= 48;
                    
                    // close any previously open recorder file.
                    if (recorder_mode != NOT_RECORDING)
                    {
                        fclose(recorder);

                        if (reg_enum_flag)
                            fclose(recorder_regs);
                    }

                    printf("entering recorder mode %d, register enumeration is %s.\n", option, (reg_enum_flag ? "enabled" : "disabled"));
                    recorder_mode = option;

                    // create/open recorder file.
                    sprintf(filename, "%s.%d", target, option);
                    recorder = fopen(filename, "a+");

                    // create/open the register recording file if the register enumeration flag is raised.
                    if (reg_enum_flag)
                    {
                        sprintf(filename, "%s-regs.%d", target, option);
                        recorder_regs = fopen(filename, "a+");
                    }
                    break;

                // detach from debuggee.
                case 'd':
                    if (!dbg.pDebugActiveProcessStop || !dbg.pDebugSetProcessKillOnExit)
                    {
                        printf("\ndetaching is not possible on the current os ... request ignored.\n");
                        break;
                    }

                    main_terminate = true;
                    printf("\nclosing any open recorder and detaching ...\n");

                    if (recorder_mode != NOT_RECORDING)
                    {
                        fclose(recorder);

                        if (reg_enum_flag)
                            fclose(recorder_regs);
                    }

                    dbg.detach();

                    break;

                // display available options.
                case 'h':
                    ps_commands();
                    break;
                
                // display memory map for executable sections of each module.
                case 'm':
                    dbg.ReBuildMemoryMap();

                    printf("\n---------- MODULE LIST ----------\n");

                    for (it = dbg.MemoryMap.begin(); it != dbg.MemoryMap.end(); ++it)
                    {
                        // determine the correct section)
                        if ((it->second->basics.Protect & PAGE_EXECUTE)           ||
                            (it->second->basics.Protect & PAGE_EXECUTE_READ)      ||
                            (it->second->basics.Protect & PAGE_EXECUTE_READWRITE) ||
                            (it->second->basics.Protect & PAGE_EXECUTE_WRITECOPY))
                        {
                            // module executable section found.
                            printf("module %08x %s\n", it->second->address, it->second->Name.c_str());
                        }
                    }

                    printf("\nstalking:\n");

                    for (node *cursor = bp_modules; cursor != NULL; cursor = cursor->next)
                        printf("%08x - %08x [%08x] %s\n", cursor->base, cursor->base + cursor->size, cursor->size, cursor->name);

                    printf("---------- MODULE LIST ----------\n\n");

                    break;

                // quit program.
                case 'q':   
                    main_terminate = true;
                    printf("\nclosing any open recorder and quiting ...\n");

                    if (recorder_mode != NOT_RECORDING)
                    {
                        fclose(recorder);

                        if (reg_enum_flag)
                            fclose(recorder_regs);
                    }

                    break;
                
                // toggle verbosity. ie: display per breakpoint disassembly.
                case 'v':
                    disassemble_flag = !disassemble_flag;

                    printf("turning breakpoint disassembly: %s\n", (disassemble_flag) ? "ON" : "OFF");
                    break;

                // close active recorder mode.
                case 'x':
                    if (recorder_mode == NOT_RECORDING)
                        break;
                    
                    fclose(recorder);

                    if (reg_enum_flag)
                        fclose(recorder_regs);

                    printf("closing recorder mode %d\n", recorder_mode);
                    recorder_mode = NOT_RECORDING;
                    break;
                
                default:
                    ps_commands();
            }   // switch
        }       // _kbhit
    }           // while

    // Debugger class will handle it's own cleanup.
    // XXX - we don't free the bp_module list.
    return 0;
};