Announcement

Collapse
No announcement yet.

Capture Gridviev/Listview text

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Mattias
    replied
    >As they say: This is not a drill!!!...that is already been used to leech the data.

    Had I known that, I would have billed you.

    Leave a comment:


  • Francisco Castanedo
    replied
    Got it!. Thanks Michael.

    Edite Out. Found the answer.

    ---------------------------------------------

    As they say: This is not a drill!!!.

    I´m really turning all this to my app in order to defeat a spy program (which one, I don´t know) that is already been used to leech the data. We encrypt this data since is the real value of our software. Whomever is reading it, is already selling it in the black market. We want to stop this. It´ll take a couple of month (maybe less) for us to find out.

    Whatever the outcome, I´ll let you know.

    I just hope the listview behaves just the same without further re-writing.
    But I suspect that M$ never intended that.
    Last edited by Francisco Castanedo; 26 Jan 2009, 12:57 PM.

    Leave a comment:


  • Michael Mattias
    replied
    I now wonder if this is enough protection against other spyware?.

    If they all use the same method (allocating a virtual memory for the listview) then, for now, we are safe.
    I personally cannot think of any way to get the text in a control other than asking for it. And if it does not answer?...

    Hmm, that line has reminded me of the old Mickey and Sylvia song...

    Oh, Listview?
    And if he doesn't answer?

    Oh, my sweet listview?
    And if he still doesn't answer?

    ....


    MCM

    Leave a comment:


  • Michael Mattias
    replied
    I noticed that after drawing the text, the selected bar was missing. my question is if by using this method are we supposed to draw EVERYTHING in the lsitview?
    Yes.

    The code which does this is in my post above, repeated here:
    Code:
    [' much edited here]
    I think I do pretty much the same thing I edited out above in the multiple-checkbox demo.

    But the key is here (from above, not from multi-checkbox demo):
    Code:
     
     CASE    %CDDS_ITEMPREPAINT
                   iSelRow     = @plvu.LVCD.nmcd.dwItemSpec  'which row to draw
    This tells you which row to draw. Later you can ..

    Code:
       bSelected = (Listview_GetItemSTate (@plvu.nmhdr.HwndFrom, iSelRow, %LVIS_SELECTED) AND %LVIS_SELECTED)
    This tells you if this row is selected or not. If it's selected, you set the text color and background differently than if that row is not selected, and pass the appropriate parameters to FillRect (to erase previous text/image) and drawText (to set text color and the background color).

    MCM

    Leave a comment:


  • Francisco Castanedo
    replied
    Well, after making a working virtual listview (just working enough to test) and having Listview Spy try to steal the text data, I must say that you were right Michael. Listview Spy couldn´t get the data out from the control.

    I now wonder if this is enough protection against other spyware?.

    If they all use the same method (allocating a virtual memory for the listview) then, for now, we are safe.


    I noticed that after drawing the text, the selected bar was missing. my question is if by using this method are we supposed to draw EVERYTHING in the lsitview?

    Leave a comment:


  • Francisco Castanedo
    replied
    Ok Michael. I followed your lead but my knwoledge base is not as big as yours so I got to a point where I got stuck.

    I took a sample Virtual Listview program and modified it with the code you showed above. Only thing is I can´t seem to get it to work.

    I attached the code for you to review and fix (if you choose to do so, of course).

    I commented out all code I think is not relevant.

    ADDED LATER: GOT IT!. It´s working now. After adjusting some things, I finally made it work. I´ll throw Listview Spy at it and see what happens.

    I posted the working code instead.
    Attached Files
    Last edited by Francisco Castanedo; 25 Jan 2009, 02:20 PM.

    Leave a comment:


  • Michael Mattias
    replied
    >Well then, how are you supposed to get the data into the listview?

    You don't. You must use a VIRTUAL listview (LVS_OWNERDATA) and store the data "somewhere else."

    You must also completely draw the items and subitems yourself on NM_CUSTOMDRAW. ie, every response to the NM_CUSTOMDRAW notifications must be CDRF_SKIPDEFAULT.

    Here's how I do this (code edited )...

    Code:
                                   CASE %NM_CUSTOMDRAW    ' returns nmcd
    
                                       SELECT CASE AS LONG @plvu.LVCD.nmcd.dwDrawStage
    
                                           CASE %CDDS_PREPAINT
                                              'STDOUT "Got CDDS_PREPAINT"
                                             ' tell Windows we want separate notify for each item
                                               FUNCTION           = %CDRF_NOTIFYITEMDRAW
                                               EXIT                 FUNCTION
    
                                             ' we expect this message because we requested the NOTOFYITEMDRAW
                                           CASE    %CDDS_ITEMPREPAINT
    
                                               [' much edited here]
    
                                                ' get the correct icon from the image list (or other source)
                                               iImageIndex     = GetNodeImageIndex (BYVAL pNode)
                                                ' draw the image with X offset by %IMAGE_WIDTH * depth
                                               ImageList_Draw  _
                                                      hIl,_
                                                      iImageIndex, _                           ' image index
                                                      @plvu.lvcd.nmcd.hdc, _                   ' device context
                                                      R.nLeft + (%IMAGE_WIDTH*@pNode.Level), _ ' X
                                                      R.nTop, _                                ' Y
                                                      %ILD_NORMAL                              ' flags
    
                                                   ' add the text in the assigned area, with ellipses if necessary..
                                               DrawText  @plvu.lvcd.nmcd.hdc, _
                                                        szText, _
                                                        lstrlen(szText), _
                                                        TextRect, _
                                                        %DT_NOPREFIX OR %DT_END_ELLIPSIS
    
                                               ' and tell Windows the painting has been handled
                                               FUNCTION         = %CDRF_SKIPDEFAULT
                                               EXIT               FUNCTION
    
                                       END SELECT   ' of draw stage under NM_CUSTOMDRAW for VTV
    This example is from application with only one column, but the demo you looked at earlier shows you can also do this at the subitem level, completely drawing the subitem when dwDrawState = (%CDDS_ITEMPREPAINT OR %CDDS_SUBITEM) and returning CDRF_SKIPDEFAULT.

    That demo, you will note, saves the text with the control, it is NOT virtual listview; AND it tells Windows to handle the painting normally on the non-checkbox columns. For those non-checkbox columns, the text is stored with the item/subitem so there is no need to intercept WM_NOTIFY/LVN_GETDISPINFO (if it's even sent)

    MCM

    Leave a comment:


  • Francisco Castanedo
    replied
    Well then, how are you supposed to get the data into the listview?

    Nevertheless, since we want to protect the data that is already IN the listview control we must find ways to deceive the intruder.

    The first thing Listview Spy (and any other spy program) does is to identify the window that contains the listview: hDlgSource = FindWindow(BYVAL %NULL, zCaption) where zCaption MUST be supplied by the hacker (read from the screen is the primary way of obtaining the name).
    Replacing all empty spaces (CHR$(32)) with CHR$(160) in the Window or Dialog Caption helps confuse the intruder. CHR$(160) is the only other ASCII character I found to be shown as an empty space, just like CHR$(32). This little decepcion works as our first line of defense but is not enough.

    I tested it with Listview Spy (can´t recognize the window), NewSpy and Winspector (this two shows the name of the window but you see SPACES instead of CHR$(160))

    If there's a more thorough or refined spy-and-hack program, the hacker won´t ever know that we changed CHR$(32)s with CHR$(160)s, so let me see if I can find something else that might work.

    BTW, ANY help will be greatly appreciated.
    Last edited by Francisco Castanedo; 24 Jan 2009, 09:01 PM.

    Leave a comment:


  • Michael Mattias
    replied
    well, right here....
    Code:
    CASE %LVN_GETDISPINFO
                                     ' Obtain the LV_DISPINFO pointer from CBLPARAM
                                     pLVDI = CBLPARAM
    
                                     'virtual ListView asks for Item text
                                     IF (@pLVDI.item.mask AND %LVIF_TEXT) THEN
                                         ' TELL ALL: 
    [COLOR="Red"]                                      @pLVDI.item.pszText = VARPTR(szName)[/COLOR]
    You tell Windows (or whomever is asking) what the text is for that row and column

    Y'all cannot tell ANYONE if you want it to remain a secret.

    Leave a comment:


  • Francisco Castanedo
    replied
    Found this

    MainDlg_OnKeyDown intercepts two keys: F5 refreshes the list view (i.e. populates it with some sample items), and DEL erases its content. Nothing ensures that the list view is stable at the moment of operations (i.e. you can press DEL during a list view update). You have to protect the list view on your own. Perhaps the best (and simplest) mechanism is to reflect the notifications (as the ON_NOTIFY_REFLECT does) to the list view, so the control will know how to operate on its data, styles, content etc. and how to avoid side effects or concurrent access.
    at

    List view sort on header click and showing 'No items' with 'More' tooltip


    It may be of some help although I don´t understand C

    Leave a comment:


  • Francisco Castanedo
    replied
    I encrypted the data but Listview Spy reads it directly from the listview already unencrypted.

    I put a decrypt routine in the %WM_NOTIFY/%LVN_GETDISPINFO in order to hand the data readable for the listview. So I infer that listview Spy commands and extracts the data directly from the control, and the control puts the data inside itself using the routines provided by the original program. Very sneaky!.


    Here is the relevant code in the callback that handles the listview data:
    (without the decrypt thingy)

    Code:
        LOCAL  pNMLV              AS NM_LISTVIEW PTR
        LOCAL  pLVDI              AS LV_DISPINFO PTR
        LOCAL  lpLVCD             AS NMLVCUSTOMDRAW PTR
        LOCAL  szName             AS ASCIIZ * 256
        LOCAL  KeyDown            AS LV_KEYDOWN PTR
    
    '   pGuia$() is a global string arrary that contains the listview data. All fields within each element (record) are sparate by the "ÏÏÏ" string
    
              CASE %WM_NOTIFY
    
    
                   ' The WM_NOTIFY message informs the parent window of a control that an event has
                   ' occurred in the control or that the control requires some kind of information.
    
                   ' Handle ListView notifications only
    
    
                   IF LOWRD(CBWPARAM) <> %IDC_VLV_PARTIDAS THEN EXIT SELECT
    
    
                        ' Obtain the NM_LISTVIEW pointer from CBLPARAM
                        pNMLV = CBLPARAM
    
                        ' Obtain the LV_KEYDOWN pointer from CBLPARAM
                        KeyDown = CBLPARAM
    
                        SELECT CASE @pNMLV.hdr.code
    
    
                               CASE %NM_CUSTOMDRAW
                                    IF SelectFunc.MostrarLineasguia& = 0 THEN
                                         lpLVCD = CBLPARAM
                                         IF(@lpLVCD.nmcd.dwDrawStage = %CDDS_PREPAINT) THEN
                                             FUNCTION = %CDRF_NOTIFYITEMDRAW
                                             EXIT FUNCTION
                                         END IF
                                         IF(@lpLVCD.nmcd.dwDrawStage =  %CDDS_ITEMPREPAINT)  THEN
                                             IF (@lpLVCD.nmcd.dwItemSpec MOD 2) = 0 THEN
                                             ' Linea Guia
                                              @lpLVCD.clrTextBk = RGB(225,225,225)        'Item Text Background Color
                                             END IF
    
                                             FUNCTION = %CDRF_NEWFONT                        'Return CDRF_NOTIFYSUBITEMREDRAW
                                                                                             'to customize the item's subitems individually then
                                                                                             'case CDDS_SUBITEM | CDDS_ITEMPREPAINT
                                             EXIT FUNCTION
                                         END IF
                                    END IF
    
    
                                CASE %LVN_GETDISPINFO
    
    
                                     ' Obtain the LV_DISPINFO pointer from CBLPARAM
                                     pLVDI = CBLPARAM
    
                                     'virtual ListView asks for Item text
                                     IF (@pLVDI.item.mask AND %LVIF_TEXT) THEN
    
                                             ' Recalcular Precio Unitario
                                             IF @pLVDI.item.iSubItem = 7 AND TRIM$(PARSE$(pGuia$(@pLVDI.item.iItem), "ÏÏÏ", @pLVDI.item.iSubItem)) = "0,00" THEN
                                                  PrecioUnitarioLV (@pLVDI.item.iItem)  ' External SUB that calculates a value
                                             END IF
    
                                             ' Recalcular Precio Unitario si ha habido exclusion/sustitucion de insumo
                                             IF @pLVDI.item.iSubItem = 7 AND CambioInsumo = 1 THEN
    
                                                  PrecioUnitarioLV (@pLVDI.item.iItem)  ' External SUB that calculates a value
                                             END IF
    
                                             szName = PARSE$(pGuia$(@pLVDI.item.iItem), "ÏÏÏ", @pLVDI.item.iSubItem)
                                             @pLVDI.item.pszText = VARPTR(szName)
    
                                     END IF
    
    
                                     ' Here we notify the listview that this item has a state image
                                     IF (@pLVDI.item.mask AND %LVIF_IMAGE) THEN
    
                                          ' in order for the listview to show the state images
                                          ' the mask and statemask must be set to the following
                                          ' parameters
    
                                          @pLVDI.item.mask =%LVIF_STATE OR %LVIF_TEXT
                                          @pLVDI.item.statemask =%LVIS_STATEIMAGEMASK
                                     END IF
    
                                     'virtual ListView asks for Item state image
                                     IF (@pLVDI.item.mask AND %LVIF_STATE) THEN
    
                                          SELECT CASE VAL(PARSE$ (pGuia$(@pLVDI.item.iItem), "ÏÏÏ", lColCount))
                                               CASE 0
                                                    @pLVDI.item.state = INDEXTOSTATEIMAGEMASK(1)
                                               CASE 1
                                                    @pLVDI.item.state = INDEXTOSTATEIMAGEMASK(2)
                                          END SELECT
    
                                     END IF
    
    
                        END SELECT

    Leave a comment:


  • Michael Mattias
    replied
    > have an application that uses WM_NOTIFY/LVN_GETDISPINFO

    Are you eating this notification? Code not shown. (Just return a null string). (Or maybe cooler: "NO HACKING PLEASE")

    I have no idea how this listview spy app works, other than it sending a LVM_GETITEM to the control, requesting text. If this is a virtual or LPSTR_CALLBACK item, WM_NOTIFY/LVN_GETDISPINFO is generated to ask control for that text.

    If LVN_GETDISPINFO returns nothing, the requester gets nothing.

    Leave a comment:


  • Francisco Castanedo
    replied
    I have an application that uses WM_NOTIFY/LVN_GETDISPINFO, WM_NOTIFY/NM_CUSTOMDRAW and is an LVS_OWNERDATA Listview.

    The Listview Spy reads it right "out of the box" (I mean after copying and pasting the code into de PB editor).

    I´m going to encrypt the data before it is placed in the listview so I will know (more or less) how the hacking routines work.

    Leave a comment:


  • Michael Mattias
    replied
    If I understood you correctly, using WM_NOTYFY/NM_CUSTROMDRAW as described should prevent another program (e.g. Listview Spy) from reading the listview data
    I hope I did not leave that impression, because that alone is insufficient.

    The control has to also 'eat' WM_NOTIFY/LVN_GETDISPINFO, which I think is only sent when the control is either style LVS_OWNERDATA or the lvitem.pszText is set to LPSTR_TEXTCALLBACK.

    Effectively the ONLY way to do it is to ensure that Windows - or another process - is never given the text when it asks...which means you must refuse to supply the text on WM_NOTIFY/LVN_GETDISPINFO .. which further means you will have to draw each item yourself on WM_NOTIFY/NM_CUSTOMDRAW, since Windows does not have what it needs to do that drawing.

    Leave a comment:


  • Francisco Castanedo
    replied
    Originally posted by Michael Mattias View Post
    Just one more thing... with listviews, "Owner-Draw" is more or less automatic.. you don't need to use any special style when creating the control, you just have to intercept the WM_NOTIFY/NM_CUSTOMDRAW notification and either tell it to "do the default action" or "do something yourself."

    This is demo'd here: Listview with Multiple Checkbox Columns Demo 2-20-05

    MCM
    If I understood you correctly, using WM_NOTYFY/NM_CUSTROMDRAW as described should prevent another program (e.g. Listview Spy) from reading the listview data.

    I tried your demo and could extract the data right away.

    Code:
    hDlgSource = B07AA
    hListview = E074C
    lvCount = 12
    hThread = BFC
    pid = D08
    hProcess = C4
    pListviewItem = B00000
    pzItem = B10000
    pHdItem = B20000
    lvColumnCount =  9
    
    
    Name    Height    Weight    Hair Color    Eye Color    Cycle    Trk/Lt    Trk/Hvy    Boat    
    
    
    Smith, John    5-10    145    BLD    BLUE    Y    N    N    N    
    
    Jones, Mary    5-2    121    BRN    BRN    N    Y    Y    N    
    
    Kane, Horatio    6-0    175    BLD    BLUE    Y    N    N    Y    
    
    O'Neal, Shaquille    7-1    325    SHAVED    BRN    Y    Y    N    N    
    
    Gordon, Flash    6-1    210    BLD    BLUE    N    Y    N    N    
    
    Kent, Clark    6-2    225    BLK    GRN    Y    Y    Y    Y    
    
    Lane, Lois    5-5    134    BLK    BRN    N    Y    Y    Y    
    
    Olson, Jimmy    5-8    155    RED    GRN    N    Y    Y    N    
    
    Wayne, Bruce    6-1    195    BLD    BLUE    Y    N    Y    Y    
    
    Parker, Peter    5-10    168    BLK    GRN    Y    N    N    N    
    
    Cartwright, Hoss    6-2    307    BLD    BLUE    N    Y    N    N    
    
    Banner, Dr. David    5-11    180    BRN    BRN    N    Y    N    Y

    Leave a comment:


  • Adrian Verkuil
    replied
    MM,

    This tool is super, there is a thread somewhere on this forum about it.

    I use it for ... years, is a must have tool, will get anything, well almost I guess

    For example getting text from a listview, select capture text and dont forget to set the autoscroll on, then simple point at the box and YES a txt file as result, how they do it ?? somehow they get what a control is about in their enum no matter what it is called, not sure if it can capture all , but the one I needed was a funny name and a superclassed one at least winspy told me that.

    Good Luck,

    You will like it , can do a lot more then only capture.

    Leave a comment:


  • Michael Mattias
    replied
    Well, "Snagit" is currently on my personal to-do list (buy, install, test).

    I thought Snagit just did screen captures with annotations and draw circles around pieces of screen captures..., which is all I want it for.

    I never thought it could return "control text" to, say, .. where? the clipboard? An edit control?

    Leave a comment:


  • Adrian Verkuil
    replied
    Hi MM,

    Still I wonder how Snagit does it , it managed to get data out of a listview with a funny name "datv123lst" so somehow they manage to do a enum and find out what a control is bye code!!

    Nah, when more time I will try if you can try setting's that if TRUE tell you what kind off control your code is looking at. I think thats the way they do it.

    Leave a comment:


  • Michael Mattias
    replied
    Just one more thing... with listviews, "Owner-Draw" is more or less automatic.. you don't need to use any special style when creating the control, you just have to intercept the WM_NOTIFY/NM_CUSTOMDRAW notification and either tell it to "do the default action" or "do something yourself."

    This is demo'd here: Listview with Multiple Checkbox Columns Demo 2-20-05

    Some columns are drawn manually, but some for some columns Windows is allowed to perform the default action. And in any event, even for the owner-drawn columns (the checkboxes), the control stores text for the items. (I store "Y" or "N" for the checkbox columns so I know if I should draw the check box in a checked or unchecked state).

    Contrast this with using the LVS_OWNERDATA style... when this is used, the control stores essentially nothing, and Windows asks for display info via the WM_NOTIFY/LVN_GETDISPINFO message whenever a row or column needs to be repainted. In this case you are responsible for storing all the info necessary to effect a redraw when required, such storage being outside the control. Yes, in this case you can tell Windows to do the default drawing on NM_CUSTOMDRAW, but when you do that windows says, "Ok, fine, I'll draw it.. but you will have to give me the icon handle and the text when I send you WM_NOTIFY/LVN_GETDISPINFO"

    i.e., handling "systlistview32" controls is not quite as simple as using a text control.. all that power comes at the cost of more programming.


    MCM

    Leave a comment:


  • Michael Mattias
    replied
    >Good news, I did some test on ownerdrawn listview with <ListView spy>...

    That's because the author carelessly (foolishly?) forgot to 'eat' the WM_NOTIFY/LVN_GETDISPINFO notification.

    MCM

    Leave a comment:

Working...
X
😀
🥰
🤢
😎
😡
👍
👎