Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Logging registers at a specific code

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Geri
Moderator
Reputation: 111

Joined: 05 Feb 2010
Posts: 5627

PostPosted: Wed Oct 12, 2011 10:02 am    Post subject: Logging registers at a specific code Reply with quote

This idea was in my head for a long time and others have mentioned it too so I think I am not the only one who may think that this is useful, that's why I put it here for discussion.

So the feature that I am suggesting would be similar to "find out what addresses are accessed by this code" but not with a memory address, just with a register. Eg. I would like to know that for a certain code, what were the values for EAX or any other register. It isn't rare that I am using a register to calculate a memory address even if it is not accessing to the specific address itself and it is important to know that the register is not changing it's value etc. I can check it manually anytime or I can write an AA script to log the registers in an allocated space but if it is possible to do it with the debugger too, then why not? I think it would be a useful feature.

_________________
My trainers can be found here: http://www.szemelyesintegracio.hu/cheats

If you are interested in any of my crappy articles/tutorials about CE and game hacking, you can find them here:
http://www.szemelyesintegracio.hu/cheats/41-game-hacking-articles

Don't request cheats or updates.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25833
Location: The netherlands

PostPosted: Wed Oct 12, 2011 10:28 am    Post subject: Reply with quote

So basically "find out what addresses are accessed by this code" but then also keep a record of every time it is called instead of only the first time

Is it ok if I add that as a rightclick option on a specific address so it only does it on the selected address or do you want that option from the get go? (set enabled in ce's settings)

It WILL eat up memory, especially if it's one of those instructions that get called 5000 times a second. (at least 20MB/sec ram if stack is stored too)

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Geri
Moderator
Reputation: 111

Joined: 05 Feb 2010
Posts: 5627

PostPosted: Wed Oct 12, 2011 11:18 am    Post subject: Reply with quote

I know that CE is logging the registers on firts hit and I was thinking that storing all logs with registers + stack snapshot is gigantic but if you can add that, people can still consider using it as it is useful in some situations.

What I was thinking is a bit simplified version. When you click on a code, it will not log anything, just the selected register. Eg. "find out the values of EAX register on this code". Then it could make a similar list as with the memory addresses, but instead of logging the address + value, it will log the selected register's value only.

For example a list like EAX had the value of:

00445564 12 times
00678918 10 times
0078456C 28 times

This way the user would have a clue that the selected code and the register is suitable for calculating an address or the register is changing it's value all the time on that code. I think you could throw away every other data to not consume too much space.

And since not every code is accessing to an address, maybe it could work on any code (with a hardware breakpoint on the specific code) not just on codes that are accessing to addresses. I don't know if you have to use the same type of exception handling etc if you log a register or trying to find an accessed address so I have no idea if it is different or the same.

I was thinking about writing an AA script like
1. allocate space
2. read a register
3. make a few compares to see if the register was logged already
4. if it is in the list, continue
5. if it is not, add it to the list

Maybe I could even add some kind of counter, for example if the register was logged with that value already, increase a counter value with 1.
It would work I guess, but I would have to re-shape the template every time to apply it to the specific code and the choosen register I want to log and I have no clue how to make it user friendly.


(Btw. I have opened this topic because 2 other people independently from me had the same idea, so I though that maybe we can discuss it here as it seems to be a common suggestion.)

And if it requires lot of work, just dump the idea because I can do it with script or doing it manually, but everyone likes the automatic debugging features and I thought this can be done with a small change only, adding an option to log the register instead of the memory address.

_________________
My trainers can be found here: http://www.szemelyesintegracio.hu/cheats

If you are interested in any of my crappy articles/tutorials about CE and game hacking, you can find them here:
http://www.szemelyesintegracio.hu/cheats/41-game-hacking-articles

Don't request cheats or updates.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25833
Location: The netherlands

PostPosted: Thu Oct 13, 2011 6:40 am    Post subject: Reply with quote

Oh ok, when I get time I'll look into it. (There is currently a lot to work on in ce so some stuff might be shifted to 6.3)

Also, as for doing it yourself, if you're really bored and have a lot of time on your hands(and i mean, REALLY bored), you could learn lua, then program it so it adds that option to the (context)menu in the memoryview form.
And in that function you set an onExecute breakpoint on the currently selected address and then handle the breakpoints with lua, recording and automatically continuing.
It might not be as fast as native code, but it would be userfriendly enough

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Geri
Moderator
Reputation: 111

Joined: 05 Feb 2010
Posts: 5627

PostPosted: Fri Oct 14, 2011 1:15 am    Post subject: Reply with quote

Yes, good idea. I can use the debugger with lua too. And it never hurts to learn something new, only the time pressure is problem. And it is not so important for me so take your time if you plan to add it. I can solve it fairly quickly with scripts too. Writing a short script to see if the register is always fix or changing is taking a minute only.

EDIT:
For those who care about it, I have posted a simple AA script just to check that the register has fix or not fix value. Maybe later I will make one that is logging more than 1 value but usually all I care about is that the value is fix or not.

http://forum.cheatengine.org/viewtopic.php?t=543655

_________________
My trainers can be found here: http://www.szemelyesintegracio.hu/cheats

If you are interested in any of my crappy articles/tutorials about CE and game hacking, you can find them here:
http://www.szemelyesintegracio.hu/cheats/41-game-hacking-articles

Don't request cheats or updates.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Fri Oct 14, 2011 3:12 pm    Post subject: Reply with quote

Hey Geri try this out; if you have the latest Alpha of CE6.2, add this script to your autorun folder. Just name it regrecord.lua:

Code:


--[[

    regrecord - Register Monitor for Cheat Engine 6.2
    ------------------------------------------------------------
    (c) 2011 atom0s [aka Wiccaan]
   
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   
]]--

regrecord =
{
    ------------------------------------------------
    -- Register States
    ------------------------------------------------
    regstate =
    {
        ["EAX"] = { prev = 0, count = 0 },
        ["EBX"] = { prev = 0, count = 0 },
        ["ECX"] = { prev = 0, count = 0 },
        ["EDX"] = { prev = 0, count = 0 },
        ["ESI"] = { prev = 0, count = 0 },
        ["EDI"] = { prev = 0, count = 0 },
        ["EBP"] = { prev = 0, count = 0 },
        ["ESP"] = { prev = 0, count = 0 },
        ["EIP"] = { prev = 0, count = 0 },
    },
   
    bpAddress = 0,
    bHitOnce = false,
    bIsMonitoring = false,
    frmRegRecord = nil,
   
    -----------------------------------------------------------------------------
    -- func : check_state
    -- desc : Compares our stored information to the current register value.
    -----------------------------------------------------------------------------
    check_state = function( reg_prev, reg )
        if( reg_prev.prev ~= reg ) then
            reg_prev.prev = reg;
            reg_prev.count = reg_prev.count + 1;
        end
    end,
};

-----------------------------------------------------------------------------
-- func : onOpenProcess
-- desc : Called when Cheat Engine attaches to a process.
-----------------------------------------------------------------------------
function onOpenProcess( procid )
    -- Start our script.
    regrecord.Start();
end

-----------------------------------------------------------------------------
-- func : onPopupMenuClick_RecordRegisters
-- desc : Popup menu handler for our added menu item.
-----------------------------------------------------------------------------
function onPopupMenuClick_RecordRegisters( sender )
    -- Find MemoryViewForm control..
    local memViewForm = getMemoryViewForm();
    if( memViewForm == nil or memViewForm == 0 ) then
        error( 'regrecord : Could not find MemoryViewForm!' );
    end
   
    -- Find DisassemblerView control..
    local dasmView = memoryview_getDisassemblerView( memViewForm );
    if( dasmView == nil or dasmView == 0 ) then
        error( 'regrecord : Could not find DisassemblerView control!' );
    end

    -- Obtain current selected address..
    local startAddress = disassemblerview_getSelectedAddress( dasmView );
   
    -- Remove previous information..
    if( regrecord.bpAddress > 0 ) then
        debug_removeBreakpoint( regrecord.bpAddress );
       
        regrecord.bHitOnce = false;
        regrecord.bIsMonitoring = false;
       
        -- If same address, toggle this feature..
        if( regrecord.bpAddress == startAddress ) then
            regrecord.bpAddress = 0;
            return;
        end
       
        regrecord.bpAddress = 0;
    end

    -- Reset previous state information..
    for k, v in pairs( regrecord.regstate ) do
        v.prev  = 0;
        v.count = 0;
    end
   
    -- Start debugger and set breakpoint..
    debugProcess();
    debug_setBreakpoint( startAddress, nil, nil );
   
    regrecord.bpAddress = startAddress;
    regrecord.bHitOnce  = false;
    regrecord.bIsMonitoring = true;
   
    -- Create monitoring form to display values..
    if( regrecord.frmRegRecord == nil ) then
        regrecord.frmRegRecord = createForm( true );
    end
   
    control_setCaption( regrecord.frmRegRecord, 'RegRecorder - by atom0s' );
    form_centerScreen( regrecord.frmRegRecord );
    form_onClose( regrecord.frmRegRecord, function( )
        regrecord.frmRegRecord = nil;
        onPopupMenuClick_RecordRegisters( self );
        return caFree;
    end );
   
    -- Create controls on form to display values..
    local offset = 5;
    for k, v in pairs( regrecord.regstate ) do
        local label = createLabel( regrecord.frmRegRecord );
        control_setCaption( label, string.format( "%s:", tostring( k ) ) );
        control_setPosition( label, 5, offset );
        component_setName( label, string.format( "lbl_%s", tostring( k ) ) );
       
        local text1 = createEdit( regrecord.frmRegRecord );
        control_setCaption( text1, tostring( v.prev ) );
        control_setPosition( text1, 50, offset );
        component_setName( text1, string.format( "txt_%s_prev", tostring( k ) ) );
       
        local text2 = createEdit( regrecord.frmRegRecord );
        control_setCaption( text2, tostring( v.count ) );
        control_setPosition( text2, 125, offset );
        component_setName( text2, string.format( "txt_%s_count", tostring( k ) ) );
       
        offset = offset + 20;
    end   
end

-----------------------------------------------------------------------------
-- func : debugger_onBreakpoint
-- desc : Handler for when a breakpoint is hit.
-----------------------------------------------------------------------------
function debugger_onBreakpoint( )
    -- Only record if we are monitoring..
    if( regrecord.bIsMonitoring == false ) then
        return 0;
    end

    -- First hit set our values..
    if( regrecord.bHitOnce == false ) then
        regrecord.regstate["EAX"].prev = EAX;
        regrecord.regstate["EBX"].prev = EBX;
        regrecord.regstate["ECX"].prev = ECX;
        regrecord.regstate["EDX"].prev = EDX;
        regrecord.regstate["ESI"].prev = ESI;
        regrecord.regstate["EDI"].prev = EDI;
        regrecord.regstate["EBP"].prev = EBP;
        regrecord.regstate["ESP"].prev = ESP;
        regrecord.regstate["EIP"].prev = EIP;
       
        regrecord.bHitOnce = true;
        return 1;
    end
   
    -- Every other time we hit our breakpoint.. update values and counts..
    regrecord.check_state( regrecord.regstate["EAX"], EAX );
    regrecord.check_state( regrecord.regstate["EBX"], EBX );
    regrecord.check_state( regrecord.regstate["ECX"], ECX );
    regrecord.check_state( regrecord.regstate["EDX"], EDX );
    regrecord.check_state( regrecord.regstate["ESI"], ESI );
    regrecord.check_state( regrecord.regstate["EDI"], EDI );
    regrecord.check_state( regrecord.regstate["EBP"], EBP );
    regrecord.check_state( regrecord.regstate["ESP"], ESP );
    regrecord.check_state( regrecord.regstate["EIP"], EIP );

    -- Update our form..
   
    for k, v in pairs( regrecord.regstate ) do
        local text1 = component_findComponentByName( regrecord.frmRegRecord, string.format( "txt_%s_prev", tostring( k ) ) );
        control_setCaption( text1, tostring( v.prev ) );
       
        local text2 = component_findComponentByName( regrecord.frmRegRecord, string.format( "txt_%s_count", tostring( k ) ) );
        control_setCaption( text2, tostring( v.count ) );
    end     
    return 1;
end

-----------------------------------------------------------------------------
-- func : regrecord.Start
-- desc : Injects our menu item and prepares the disassemblerView control.
-----------------------------------------------------------------------------
regrecord.Start = function( )
    -- Find MemoryViewForm control..
    local memViewForm = getMemoryViewForm();
    if( memViewForm == nil or memViewForm == 0 ) then
        error( 'regrecord : Could not find MemoryViewForm!' );
    end

    -- Find DisassemblerView control..
    local dasmView = memoryview_getDisassemblerView( memViewForm );
    if( dasmView == nil or dasmView == 0 ) then
        error( 'regrecord : Could not find DisassemblerView control!' );
    end
   
    -- Get popup menu for dasmView control..
    local popupMenu = control_getPopupMenu( dasmView );
    if( popupMenu == nil or popupMenu == 0 ) then
        error( 'regrecord : Could not obtain dasmView popupMenu!' );
    end

    -- Ensure we only get added once..
    local menuItems = menu_getItems( popupMenu );
    for itemPos = 0, menuItem_getCount( menuItems ) - 1 do
        local menuItem = menuItem_getItem( menuItems, itemPos );
        local itemCaption = menuItem_getCaption( menuItem );
        if( itemCaption == 'Record Registers At This Location' ) then
            return ;
        end
    end

    -- Inject our menu item..
    local menuItem = createMenuItem( popupMenu );
    menuItem_setCaption( menuItem, 'Record Registers At This Location' );
    menuItem_onClick( menuItem, onPopupMenuClick_RecordRegisters );
    menuItem_add( menuItems, menuItem );
end


To use it:
1. Open Cheat Engine
2. Attach to a process as normal.
3. Open Memory Viewer and go to your desired address in the disassembler.
4. Right-click and choose the new 'Record Registers at this location' option.

A form should pop up and display the current values and their change count as the breakpoint keeps getting hit.

I wrote this rather fast and didn't really debug it / test it much. Hope this helps. Smile

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Geri
Moderator
Reputation: 111

Joined: 05 Feb 2010
Posts: 5627

PostPosted: Sun Oct 16, 2011 12:08 am    Post subject: Reply with quote

Pretty cool. It has worked well for me. Much more user friendly than my shitty AA script. If 6.2 gamma comes out, this should be stickied somewhere so people can find it and use it.
_________________
My trainers can be found here: http://www.szemelyesintegracio.hu/cheats

If you are interested in any of my crappy articles/tutorials about CE and game hacking, you can find them here:
http://www.szemelyesintegracio.hu/cheats/41-game-hacking-articles

Don't request cheats or updates.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sun Nov 13, 2011 9:32 pm    Post subject: Reply with quote

Repost

Here is v2 of the script above since the forums got nuked:

Code:


--[[

    regrecord - Register Monitor for Cheat Engine 6.2
    ------------------------------------------------------------
    (c) 2011 atom0s [aka Wiccaan]
   
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   
]]--

regrecord =
{
    ---------------------------------------------------------------------------
    -- Register entries to hold recorded information..
    ---------------------------------------------------------------------------
    regstate =
    {
        ["EAX"] = { prev = 0, count = 0, record = false },
        ["EBX"] = { prev = 0, count = 0, record = false },
        ["ECX"] = { prev = 0, count = 0, record = false },
        ["EDX"] = { prev = 0, count = 0, record = false },
        ["ESI"] = { prev = 0, count = 0, record = false },
        ["EDI"] = { prev = 0, count = 0, record = false },
        ["EBP"] = { prev = 0, count = 0, record = false },
        ["ESP"] = { prev = 0, count = 0, record = false },
        ["EIP"] = { prev = 0, count = 0, record = false },
    },
   
    bpAddress       = 0,        -- Record address where our breakpoint is set..
    bHitOnce        = false,    -- Flag to check if we've initialized..
    bIsMonitoring   = false,    -- Flag to check if we are monitoring..
    frmRegRecord    = nil,      -- Record form object..
   
    ---------------------------------------------------------------------------
    -- func : check_state
    -- desc : Compares the stored register to the current register value.
    ---------------------------------------------------------------------------
    check_state = function( reg_prev, reg )
        if( reg_prev.record == false ) then return; end
        if( reg_prev.prev ~= reg  ) then
            reg_prev.prev = reg;
            reg_prev.count = reg_prev.count + 1;
        end
    end,
};

---------------------------------------------------------------------------
-- func : onOpenProcess
-- desc : Called when Cheat Engine attaches to a process.
---------------------------------------------------------------------------
function onOpenProcess( procid )
    -- Start our script..
    regrecord:Start();
end

---------------------------------------------------------------------------
-- func : onPopupMenuClick_RecordRegisters
-- desc : Popup menu handler for our added menu item.
---------------------------------------------------------------------------
function onPopupMenuClick_RecordRegisters( sender )
    -- Find MemoryViewForm control..
    local memViewForm = getMemoryViewForm();
    if( memViewForm == nil or memViewForm == 0 ) then
        error( 'regrecord : Could not find MemoryViewForm!' );
    end

    -- Find DisassemblerView control..
    local dasmView = memoryview_getDisassemblerView( memViewForm );
    if( dasmView == nil or dasmView == 0 ) then
        error( 'regrecord : Could not find DisassemblerView control!' );
    end
   
    -- Reset our recording form..
    regrecord:ResetForm();

    -- Obtain current selected address from disassembler view..
    local startAddress = disassemblerview_getSelectedAddress( dasmView );
   
    -- Cleanup previous information if we were used before..
    if( regrecord.bpAddress > 0 ) then
        -- Remove previous breakpoint if set..
        debug_removeBreakpoint( regrecord.bpAddress );
   
        -- Cleanup flags..
        regrecord.bHitOnce      = false;
        regrecord.bIsMonitoring = false;
       
        -- Toggle this feature if we were set on same address..
        if( regrecord.bpAddress == startAddress ) then
            form_hide( regrecord.frmRegRecord );
            regrecord.bpAddress = 0;
            return;
        end
       
        regrecord.bpAddress = 0;
    end

    -- Cleanup previous register state information..
    for k, v in pairs( regrecord.regstate ) do
        v.prev      = 0;
        v.count     = 0;
        v.record    = false;
    end
   
    -- Start debugger and set breakpoint..
    debugProcess();
    debug_setBreakpoint( startAddress, nil, nil );
   
    -- Prepare variables..
    regrecord.bpAddress     = startAddress;
    regrecord.bHitOnce      = false;
    regrecord.bIsMonitoring = true;
   
    -- Ensure the form is created..
    if( regrecord.frmRegRecord == nil ) then
        regrecord:Start();
    end
   
    -- Update address label..
    local label = component_findComponentByName( regrecord.frmRegRecord, "lbl_addr_loc" );
    control_setCaption( label, string.format( "Recording registers at: 0x%08X", regrecord.bpAddress ) );
   
    -- Show our form..
    form_show( regrecord.frmRegRecord );
end

---------------------------------------------------------------------------
-- func : ResetForm
-- desc : Cleans the form and resets its default values.
---------------------------------------------------------------------------
function regrecord:ResetForm( )
    if( self.frmRegRecord == nil ) then
        return;
    end
   
    for k, v in pairs( self.regstate ) do
        local text1 = component_findComponentByName( self.frmRegRecord, string.format( "txt_prev_%s", tostring( k ) ) );
        control_setCaption( text1, 0 );
       
        local text2 = component_findComponentByName( self.frmRegRecord, string.format( "txt_count_%s", tostring( k ) ) );
        control_setCaption( text2, 0 );
       
        local checkbox = component_findComponentByName( self.frmRegRecord, string.format( "chk_%s", tostring( k ) ) );
        checkbox_setState( checkbox, false );
       
        v.prev      = 0;
        v.count     = 0;
        v.record    = false;
    end
   
    -- Update address label..
    local label = component_findComponentByName( regrecord.frmRegRecord, "lbl_addr_loc" );
    control_setCaption( label, string.format( "Recording registers at: 0x%08X", 0 ) );
end

---------------------------------------------------------------------------
-- func : debugger_onBreakpoint
-- desc : Called when Cheat Engine hits a breakpoint.
---------------------------------------------------------------------------
function debugger_onBreakpoint( )
    -- Skip breakpoint if we aren't monitoring..
    if( regrecord.bIsMonitoring == false ) then
        return 1;
    end
   
    -- If first hit, store current register values..
    if( regrecord.bHitOnce == false ) then
        regrecord.regstate["EAX"].prev = EAX;
        regrecord.regstate["EBX"].prev = EBX;
        regrecord.regstate["ECX"].prev = ECX;
        regrecord.regstate["EDX"].prev = EDX;
        regrecord.regstate["ESI"].prev = ESI;
        regrecord.regstate["EDI"].prev = EDI;
        regrecord.regstate["EBP"].prev = EBP;
        regrecord.regstate["ESP"].prev = ESP;
        regrecord.regstate["EIP"].prev = EIP;
        regrecord.bHitOnce = true;
    else
        -- Update register information..
        regrecord.check_state( regrecord.regstate["EAX"], EAX );
        regrecord.check_state( regrecord.regstate["EBX"], EBX );
        regrecord.check_state( regrecord.regstate["ECX"], ECX );
        regrecord.check_state( regrecord.regstate["EDX"], EDX );
        regrecord.check_state( regrecord.regstate["ESI"], ESI );
        regrecord.check_state( regrecord.regstate["EDI"], EDI );
        regrecord.check_state( regrecord.regstate["EBP"], EBP );
        regrecord.check_state( regrecord.regstate["ESP"], ESP );
        regrecord.check_state( regrecord.regstate["EIP"], EIP );
    end
   
    -- Update form controls with new information..
    for k, v in pairs( regrecord.regstate ) do
        local text1 = component_findComponentByName( regrecord.frmRegRecord, string.format( "txt_prev_%s", tostring( k ) ) );
        control_setCaption( text1, tostring( v.prev ) );
       
        local text2 = component_findComponentByName( regrecord.frmRegRecord, string.format( "txt_count_%s", tostring( k ) ) );
        control_setCaption( text2, tostring( v.count ) );
    end
   
    return 1;
end

---------------------------------------------------------------------------
-- func : regrecord:InjectMenu
-- desc : Injects our menu item into the disassembler window.
---------------------------------------------------------------------------
function regrecord:InjectMenu( )
    -- Find MemoryViewForm control..
    local memViewForm = getMemoryViewForm();
    if( memViewForm == nil or memViewForm == 0 ) then
        error( 'regrecord : Could not find MemoryViewForm!' );
    end

    -- Find DisassemblerView control..
    local dasmView = memoryview_getDisassemblerView( memViewForm );
    if( dasmView == nil or dasmView == 0 ) then
        error( 'regrecord : Could not find DisassemblerView control!' );
    end
   
    -- Get popup menu for dasmView control..
    local popupMenu = control_getPopupMenu( dasmView );
    if( popupMenu == nil or popupMenu == 0 ) then
        error( 'regrecord : Could not obtain dasmView popupMenu!' );
    end

    -- Ensure we only get added once..
    local menuItems = menu_getItems( popupMenu );
    for itemPos = 0, menuItem_getCount( menuItems ) - 1 do
        local menuItem = menuItem_getItem( menuItems, itemPos );
        local itemCaption = menuItem_getCaption( menuItem );
        if( itemCaption == 'Record Registers At This Location' ) then
            return ;
        end
    end

    -- Inject our menu item..
    local menuItem = createMenuItem( popupMenu );
    menuItem_setCaption( menuItem, 'Record Registers At This Location' );
    menuItem_onClick( menuItem, onPopupMenuClick_RecordRegisters );
    menuItem_add( menuItems, menuItem );
end

---------------------------------------------------------------------------
-- func : regrecord.Start
-- desc : Prepares our script for use.
---------------------------------------------------------------------------
function regrecord:Start( )
    -- Inject the menu item if needed..
    self:InjectMenu();

    -- Skip the rest if we have a form created already..
    if( self.frmRegRecord ~= nil ) then
        return;
    end
   
    -- Create form and set closing action to hide..
    self.frmRegRecord = createForm( false );
    form_centerScreen( self.frmRegRecord );
    control_setCaption( self.frmRegRecord, 'RegRecorder - by atom0s' );
    form_onClose( self.frmRegRecord, function( )
        -- Remove breakpoint if we were recording..
        if( self.bpAddress > 0 ) then
            onPopupMenuClick_RecordRegisters( self );
        end
        return caHide;
    end );

    -- Create and prepare form controls..
    local offset = 5;
    for k, v in pairs( self.regstate ) do
        -- Create record checkboxes..
        local checkbox = createCheckBox( self.frmRegRecord );
        control_setCaption( checkbox, string.format( '%s:', tostring( k ) ) );
        control_setPosition( checkbox, 5, offset+3 );
        component_setName( checkbox, string.format( 'chk_%s', tostring( k ) ) );
        checkbox_onChange( checkbox, function( sender )
            local name = component_getName( sender );
            local reg  = name:match( "_(%w+)" );
            regrecord.regstate[reg].record = not regrecord.regstate[reg].record;
        end );
       
        -- Create record value editbox..
        local textbox = createEdit( self.frmRegRecord );
        control_setCaption( textbox, 0 );
        control_setPosition( textbox, 50, offset );
        component_setName( textbox, string.format( 'txt_prev_%s', tostring( k ) ) );

        -- Create record value editbox..
        textbox = createEdit( self.frmRegRecord );
        control_setCaption( textbox, 0 );
        control_setPosition( textbox, 130, offset );
        component_setName( textbox, string.format( 'txt_count_%s', tostring( k ) ) );

        offset = offset + 20;
       
        -- Set default values..
        v.prev      = 0;
        v.count     = 0;
        v.record    = false;
    end
   
    -- Create address display label..
    local label = createLabel( self.frmRegRecord );
    control_setCaption( label, string.format( "Recording registers at: 0x%08X", 0 ) );
    control_setPosition( label, 5, 200 );
    component_setName( label, 'lbl_addr_loc' );
end


_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites