線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1952
推到 Plurk!
推到 Facebook!

繼承他程執行中的TStringGrid如何防止資料的互搶

尚未結案
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-26 22:43:17 IP:220.137.xxx.xxx 未訂閱
舉個例子:股市看盤A程式中使用了大量的TStringGrid(只要視窗登記的無論是Vc寫的或是VB bcb de ..寫的等等皆可) 我想進入內部中取得大量的資料以便適時的提出決策警告等等所以我大量的使用WINAPI asm寫了一個B程式 繼承了A程式執行中的TStringGrid(真正的繼承 像 MyStringGrid1->Cells[J][I] = AStringGrid1->Cells[J][I];一般的存取 ) 當我非常愉快的在使用A程式中的TStringGrid時 A程式並不知道我繼承了它的TStringGrid所以當我在讀取分析時 A程式突然改變了TStringGridS中的內容 例如原本是顯示台積電的現在變成了聯電的分時走勢圖 同時我就慘了 我試過了 用我B程式的執行緒去執行也不行 用A程式的執行緒執行也不行 因為A程式也有好幾個執行緒執行中它們自有存取機制在控制 我繼承了它但無法得到存取控制的機制所以便發生資料的互搶與不確定 似乎從執行緒下手得不到答案 請問先進們能點出方向嗎?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-27 02:01:17 IP:211.76.xxx.xxx 未訂閱
lou你好: 在看完你的說明後,有幾個問題想提出來討論,說不定可以有一些幫助。 1.程式A和程式B是不同的process嗎?如果是不同的process,memory address是完全不同的,你如何對程式A做存取?使用那個API? 2.程式B繼承了程式A的TStringGrid,但是兩者所產生的object是完全不同的物件實體,在資料上應該也是不相同的。不太了解你說的繼承是如何實作? 3.TStringGrid好像是vcl打造出來的,我記得他不是windows中已有的window class(如Button,Menu之類的)還是我記錯了?
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-27 11:47:22 IP:220.137.xxx.xxx 未訂閱
pwipwi你好; 1.程式A和程式B是不同的process嗎?如果是不同的process,memory address是完全不同的,你如何對程式A做存取?使用那個API? 回答 ; 使用VirtualQueryEx;ReadProcessMemory and WriteProcessMemory太慢了 我使用 VirtualQuery (在我的dll中使用(當然得用hook掛在A程的執行緒上)) 然後用ASM語法語言存取 2.程式B繼承了程式A的TStringGrid,但是兩者所產生的object是完全不同的物件實體,在資料上應該也是不相同的。不太了解你說的繼承是如何實作? 回答 ; 您的說法一般大致是對的 但是類別內容的成分粗分兩大類 一個是資料 第二個操作資料類別的函數 其中的第二個 是在linke中決定的 至於第一個嘛... 有兩種方式 一是在C 編譯時決定的 另一種是在執行時期決定的 我們所謂繼承的也是我們最感興趣的類別中的資料 至於類別的操作函數 我們不感興趣 用我們的不見得比較慢(就像類別的朋友函數) 所以我們進入它的執行緒之後 模擬動態產生的方式去繼承它(就像C 的NEW)我是繼承該TS類別的資料段 所以是同一個物件就像 int* a; a=new int[100]; //user in c compiler int* b; //in runtime we can do the b=a; //in runtime user this b=? =a? if a can red write b as too //-----((A程式並不知道我繼承了它的a(我以b的方式使用A真正的資料 同一個物件 如上面的極簡化程式碼))*** b and a兩者所產生的object是不是完全相同的(物件資料段)實體 在資料段上該也是相同的。不是嗎?(輕鬆一下 不要太緊張 把INT想像成一個類別 這個觀念很重唷 ) 3.TStringGrid好像是vcl打造出來的,我記得他不是windows中已有的window class(如Button,Menu之類的)還是我記錯了? 回答 ; 只是你我觀念不同而已 所有的視窗都必須向系統登記 至於如Button,Menu之類的等視窗是現成可用的視窗 而TStringGrid視窗只不過由使用著用WINDOW API所創造的 基本上跟如Button,Menu之類是一樣的 在執行期間該TStringGrid視窗也必須向系統登記 我們是一視同仁的 只不過如Button,Menu之類的視窗 系統有提供 如SendMessage(hTargetHwnd,WM_GETTEXT,255,(LPARAM)szPass);之類的存取資料之類的 而TStringGrid視窗 沒有提供 所以我們直接繼承它的資料段 (所以不管他是VB的VC的BCB的DE的它都必須向系統登記) 所以我認為它不是VCL打造的(也許在下學淺 例如VB.VC.BCB.DE等等都同一個VCL嗎?因為用它們開發的程式都有TStringGridS的類別) p.s以上中文都是請他人代打 我本身不會打中文 我只會打英文 中文一個字都要找很久 所以我的回覆很慢(因為要請他人代打)
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-27 16:32:58 IP:211.76.xxx.xxx 未訂閱
看完你詳細的說明後,大概可以知道你是用inject DLL對程式A的記憶體做直接的存取。 或許有個方式可以做到你要的需求: 在抓取程式A的資料的同時,把所有的程式A的Thread都暫停下來,用CreateRemoteThread的方式在程式A的process中產生單一的Thread, 抓取你要的資料。抓完後再讓程式A活起來。這樣就可以解決同時存取 的衝突問題。 不過這樣還會有一個潛在的問題,VCL本身的視覺化元件在設計時就只預設是 單一個Thread。因此雖然你是直接抓到了程式A的StringGrid的位址,但存取資料使用的還是VCL本身提供的函式吧?VCL中的函式都和window message有很強的關連性。如果使用VCL本身提供的函式作存取,或許可能會出問題(比如程式A的資料沒有更新,顯示錯誤之類的...)這時可能需要自行打造存取的函式了.. 另外如果我沒記錯,雖然你提到VB、VC也有Grid。不過只有BCB和DELPHI是 使用同一個vcl library。VB和VC應該是使用不同的架構。
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-27 20:53:40 IP:220.137.xxx.xxx 未訂閱
pwipwi你好; "在抓取程式A的資料的同時,把所有的程式A的Thread都暫停下來,用CreateRemoteThread的方式在程式A的process中產生單一的Thread, 抓取你要的資料。抓完後再讓程式A活起來。這樣就可以解決同時存取 的衝突問題。" 回答 ; 對於如上所說的方式pwipwi兄您的意思是否叫我暫停 程式A的Thread的時候向上天祈禱該Thread不可停在剛好再更新資料時? 對於pwipwi兄你的答題得分之高 似乎不該如此戲弄小弟吧? 到不如將我們B程式的存取程式碼推入Ring0執行,比暫停程式a的Thread更容易不是嗎? 對於您第一次提出的三個問題 憑良心說我是費了一些時間 舉了一個INT的極簡單的例子來說明三個問題我都非常慎重思考的回答您 (不回答則以 要回答我一定慎重再三不打馬呼回答 )不知您同意否? 對於您的回答 如上所言 (還要向上天祈禱該Thread 不可停在剛好再更新資料時) 好像pwipwi兄有一點...(戲弄小弟吧?) .. .. 很抱歉找不到形容詞 然而不也是如此? 閉著眼睛試想一下 股市看盤軟體 或者一些顯示資料庫資料的軟體 存取列印權限受限時...(不包括使用B程式 造假開地下期貨公司,如你看到的台機電是跌的 收盤時才漲到正確的價位...) 用單機版的付費 經由B程式取出資料 再分享給也許一百台 或者五十台 終端機 使用 而不增加網路流量 所謂一人吃五十人補 (只負單機版費用 ;一人吃 )所以我的B程式 是極具價值與實用性 所以我的所謂B程式 絕非提出聊天之用 以上如有得罪 尚請原諒
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-27 22:47:55 IP:211.76.xxx.xxx 未訂閱
lou你好: 我想我已經在上一篇就說明白了,VCL的本身就是預設單一Thread。如果擔心同時進入的問題。就必須要用其他方法解決,比如自行打造一個存取的函式來取代程式A中的函式。這篇在上一篇中我已經指出了。 我在做每一個回答的時候,我自已都會再三的考慮才回答。第一篇中所提的東西,目的在確定你的做法是否合理。之前我的拙著vcl property viewer就是在做這類的事:解讀目標程式的Heap,分析出metaclass結構、分析所有method的進入點、動態的更變資料內容。 http://delphi.ktop.com.tw/topic.php?topic_id=51329 如果對這個議題不熟或沒碰過,我也不會隨便就提出這三個問題。 至於要如何設計取代的的函式避免重入,如何更改metaclass中的vtable,都是重要的實作問題。我只是先丟出一個想法~至於lou版友說我"戲弄"你,我想真的是說之過重了吧。
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-28 14:24:57 IP:220.137.xxx.xxx 未訂閱
pwipwi你好;    你曾問;         3.TStringGrid好像是vcl打造出來的,我記得他不是windows中已  有的window class(如Button,Menu之類的)還是我記錯了? 我是這樣回答 ;             .......#&^*&^%&%&^%.......         所以我認為它不是VCL打造的(也許在下學淺 例如VB.VC.BCB.DE等等都同一個VCL嗎?因為用它們開發的程式都有TStringGridS的類別)    是否該改成這樣(使用vc vb bcb de它們開發的程式都有TStringGridS的類別<--------所以它不是VCL,不關VCL的事) 我第一次提問的第一行{舉個例子:股市看盤A程式中使用了大量的TStringGrid(只要視窗登記的無論是Vc寫的或是VB bcb de ..寫的等等皆可)}    也說明不關VCL的事 再看下面你曾問;                  2.程式B繼承了程式A的TStringGrid,但是兩者所產生的object是完全不同的物件實體,在資料上應該也是不相同的。不太了解你說的繼承是如何實作? 我是對樣回答 ;                 int* a;                 a=new int[100];        //user in c++ compiler                 int* b;                //in runtime we can do the                 b=a;                //in runtime user this b=? =a?   if a can red write b as too    以上範例的頭兩行是由他程式所創造的後兩行是我的程式所實作的,也說明了不關VCL的metaclass中的vtable,不關類別的操作函數 (這樣的格局太小 我們要的是它程向系統登記的,有hwand的視窗,不管他是VB...VC..BCB..DE ..寫的等等皆可)    以上範例的a 就像A程式創造一根香腸  該程式對香腸(類別的資料段)煎炒煮炸的方式(類別的操作函數)我都不管,重點是我用我的筷子(操作函數)夾來吃(直接繼承它的資料段)    以上的白比喻也很明白不關VCL的事, 再說的明白一點一但進入它程中所面臨的是作業系統的規則不必去面對他是否是VB...VC..BCB..DE ..寫的等等.. 再附上一張圖圖中上半部彩色的部分為股市看盤A程式,下半部沒彩色的部分是我的B程式 下半邊的右邊是我夾來吃,左邊是我夾來看的部分可看到其中第一行1,2,3,4,5,6,7,8等是A程式暗幹沒讓我們看的部分不是我加的
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-28 17:33:25 IP:211.76.xxx.xxx 未訂閱
以下是我分析了該程式的結果, 可以確定程式是由BCB或Delphi寫成 使用的都是VCL中的元件,如: TForm,TPanel,TStringGrid,TChart。    參考下面的程式架構分析:
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-11-28 18:04:36 IP:211.76.xxx.xxx 未訂閱
另外,我不確定lou版友抓取資料是用什麼方法。 不過如果是直接抓取memory的內容,可能會存在一些問題。 VCL的TStringGrid內部的資料是存放在TStringGridStrings裡面 (也就是lou版友需要的資料)。 而TStrings會隨資料的加減而動態的配置記憶體。 萬一程式把整個StringGrid的資料整個刪除後再加入。 那目標資料的記憶體位置可能就會馬上改變位置(重新配置), 這時如果程式B還是用之前的位址抓資料, 就可能會得到一組無意義的記憶體資訊,甚至發生access violation。 但是若以VCL架構來看,StringGrid是不會被重新配置的 因此如果得到TStringGrid的記憶體位置,就可以再由該位置求得 TStringGridStrings的位置。有了TStringGridStrings, 那資料等於到手了。 不過這有個前提,在抓取TStringGridStrings位置時 不能發生記憶體重新配置。因此我才會在上上一篇中指出, 需要停止程式A的所有Thread,然後再抓取資料。 資料抓完後,再重新啟動程式A的Thread。 至於停止目標式的Thread, 這個手法也有在API hook裡面使用到, 記得候捷大師網站上有一本電子書就有提到這個手法。 (應該是windows95 system programming secrets) 現在既然lou版友的程式已經可以抓到資料, 或許只要試試停止程式A中的所有Thread就可以 解決這個問題了。
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-11-28 19:31:47 IP:220.137.xxx.xxx 未訂閱
嗨pwipwi; 看了你的回覆 感謝pwiwpi的用心分析 不過暫停程式執行是行不通的(不是不能實作 是實作之後毫無意義 因為暫停 程式A的Thread 的點無法掌握 可能在動態更新中) 現在我正在思考 由掌握個系統的動態記憶體系統下手或許可一勞永逸 就像我的B程式 對於該程式是不管用什麼方式寫的 我都不管 我是由他向系統登記視窗時 開始掛勾監視掌控 我總共掛了三個系統勾(滑鼠 鍵盤 訊息)及一個局部勾子(記憶體配置api勾子) 我在想是不是記憶體配置函數沒有完全勾到 我也不確定 只能再埋頭苦幹囉 至於暫停執行緒 是不行的 理論上行不通(所以就不用實驗了),一般來說 設計一個程式必須考慮平台的問題 將來的擴充性較大 也較穩定 所以 我一再強調 不介入A程式的製作來源,只遵照window系統視窗的遊戲規則下手 所以我將此篇發表在此 定位於win的32api 而不將此篇發表於vcl元件 一開始我就想擺脫先入為主的觀念 完全遵照window系統的規則; 當我得到資料時 才以bcb的介面呈現出來 較為合情合理 不是嗎?閉門思考中...
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-11-29 02:52:25 IP:211.76.xxx.xxx 未訂閱
很可惜暫停的手法不能解決你的問題。    不過關於Hook記憶體配置的API,我有些經驗可以提供出來, 或許可以有些幫助。        以我所知道的API Hook的方式大概可以分兩類。一個是改程 式的Import Table,另一個則是直接改目標API的Code。    這兩個手法各有優缺點。如果用修改程式Import table的方 式,有可能會無法完全hook到所有的呼叫,我曾經遇到過呼叫 API時是直接call目標API的位址。這時的呼叫完全不透過Import table的轉手,因此一定hook不到。        另一個手法是修改目標API的Code,用assembly在目標API的 程式碼寫入特定的jmp code。當呼叫API時,再把原來的碼寫回 去呼叫。這個手法解決了修改Import table會漏勾的函點。可惜 的是,這個修改目標API的手法只要遇上MultiThread就會產生漏 勾問題、嚴重的可能crash。"幾乎"沒有解法...       有個方式或許可以取代Hook記憶體配置的API:直接抓Heap的 位置。    雖然MS沒有文件指明Heap會如何配置,不過還是有一些通則: (個人的歸納結果)       Heap記憶的開始點大於0x0040:0000,小於0x5A41:0000    Heap區塊的特性是           Type為Private        State為Commit        Protect是Page ReadWrite        AllocProtect是No access       (以上只是個人經驗,不保證正確)       因此如果要分析目標程式的Heap,就可以一口氣全部抓到自 已程式的記憶體內再加以分析。免去記憶體變動的困擾。下圖 是用vcl property viewer分析的記憶體圖。其中已經把可能是 Heap的區塊標示出來,或許可以參考看看..     發表人 - pwipwi 於 2004/11/29 02:54:34
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-11-29 21:04:38 IP:220.137.xxx.xxx 未訂閱
嗨pwipwi; 看了你的回覆我深深的感覺你是一個好心,熱心,有夠老實的熱心的老實人不信你請看; "有個方式或許可以取代Hook記憶體配置的API:直接抓Heap的位置。.....因此如果要分析目標程式的Heap, 就可以一口氣全部抓到自已程式的記憶體內再加以分析。免去記憶體變動的困擾" 你有夠老實,仔細想想(要靜靜的唷)一口氣抓及一大口氣抓(我都是一大口氣的)不都一樣的也會碰到記憶體變動的困擾 感謝你的熱心提供; 再請看; Heap記憶的開始點大於0x0040:0000,小於0x5A41:0000 Heap區塊的特性是 Type為Private State為Commit Protect是Page ReadWrite AllocProtect是No access 前些日子我曾提出有關heap記憶體的問題,我主要的目的是想請高手测底的討論可惜啊沒人回應; 可能大家認為不重要太簡單了; 既然你提了我就再補上一些,都虧這些B程式才得以實作; 1 只要AllocProtect是PAGE_NOACCESS<<<==可供配發Heap區 之區間 2 (AllocProtect==PAGE_NOACCESS ) AND (State==MEM_COMMIT)<<<==已配發Heap之區塊 3 (AllocProtect==PAGE_NOACCESS) AND (State==MEM_RESERVE)<<<==可供配發Heap尚未配發之區塊 所以1(區間)=2 3(大小區塊) 但是全域變數陣列列是存在下面之間; (AllocProtect是PAGE_EXECUTE_WRITECOPY) AND ((Protect是PAGE_READWRITE) OR (Protect是PAGE_EXECUTE_READWRITE)) 這樣才不至於漏掉陣列指標 以上是小弟實做B程式時所用的方式 現在正全力解決記憶體變動的問題(因為是多THREAD的關係)
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-11-29 21:37:47 IP:211.76.xxx.xxx 未訂閱
lou版友有沒有試過Trap住程式A的Tread?    如果程式A的更新是只靠Main Tread來完成的話, 在Hook到Message時(這時Main Tread處在ProcessMessage) 用個Loop把Thread抓住,不讓他回去程式A的DispatchMessage()。 這時程式A等於是被綁死。 在這個時候抓取記憶體,或許可以解決程式A正在更新的問題。    而且VCL的多緖程式都是靠Synchronize來更新, Trap住main thread,也等於把其他TThread也一起 綁死。    如果這個方式也沒用,大概只能另請版上的高手了~~ :) 技窮了~
orson
中階會員


發表:5
回覆:135
積分:58
註冊:2002-07-11

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-11-30 14:55:28 IP:211.74.xxx.xxx 未訂閱
題外話 無關技術 為什麼不直接抓取封包? 我記得,國內大部分的股票系統,他的資料封包,都是明文。 直接抓,會不會比較方便啊? Orson
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-11-30 20:43:44 IP:220.137.xxx.xxx 未訂閱
嗨pwipwi; 我第一次提問的第4行; { 用A程式的執行緒執行也不行 因為A程式也有好幾個執行緒執行中它們自有存取機制在控制 我繼承了它但無法得到存取控制的機制所以便發生資料的互搶與不確定 似乎從執行緒下手得不到答案 請問先進們能點出方向嗎? } 因為A程式有些的Thread 是不產生訊息的 非常感謝您的熱心 雖然沒有答案 我還是非常的感謝您
luo
一般會員


發表:3
回覆:7
積分:2
註冊:2003-01-26

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-11-30 20:48:00 IP:220.137.xxx.xxx 未訂閱
嗨 orson 直接裝封包太簡單了 不夠挑戰性 也不夠方便 因為有的程式不是靠抓封包, 如資料庫的處理 終將顯示在螢幕上 ,我們的B程式的目的是,只要能顯示在螢幕上的, 我們都要繼承過來得到資料進而操控它 就向那個看盤程式 就讓別人去設計 我們得到資料不是很方便嗎?(別人的老婆別人養 但卻在我門家過夜 不是很好嗎?) 如果是資料庫系統 我們也一樣得的到資料 所以抓封包的格局比較小 也比較沒有辦法適用時大部分的軟體 我們的B程式 目前發生記憶體衝突的機率也很小 兩三天才碰一次 只要能用心的解決這個問題 那用B程式就可以打遍天下所有的能顯示資料於螢幕的軟體(軟體他在寫 別人在分析 別人在實做 我們只拿資料
系統時間:2024-04-30 6:34:12
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!