JSEMTS搜尋引擎
 



Dicevo che scritto in Delphi, che un ottimo sistema di sviluppo RAD, in
questo caso piu' che adatto ad un programma che prevede l'inserimento e
l'elaborazione di strutture di dati.
La versione target la time-limited demo del programma, perfettamente
funzionante in tutte le sue funzionalit(ottimo strumento di valutazione,
continuate cos:-) fino al 30mo giorno dopo l'installazione. Da quella data in
poi il programma non parte nemmeno.
Procuratevi come al solito un debugger per Win32, meglio se quello integrato nel
Visual Studio (VisualC++) poichfaro' riferimento a quello nel resto della
trattazione; serve anche il WDasm32, questa volta decisamente piu' utile che
in altri casi per cui tenetelo a portata di mouse. Il fixup finale come di
consueto puo' essere fatto con un hexeditor (HexWorkshop p.e.) ma per i soliti
scopi didattici non affatto necessario.

Ah dimenticavo, vorrei lasciare in sospeso alcuni passaggi finali,
fondamentalmente alcune finezze possibili a crack finito, questo perchso che
solitamente chi legge un tutorial per l'appunto lo LEGGE. Io vorrei che chi
ricevesse questo tutorial ESEGUISSE i passaggi che descrivo, altrimenti tanto
varrebbe raccontarvi cosa ho mangiato ieri sera e quali suoni ho emesso dopo la
digestione. Scherzi a parte, leggere un tutorial SENZA APPLICARLO quasi come
non leggerlo affatto, per cui pensateci prima di proseguire ed al limite
tornateci sopra quando avrete la copia del programma a portata di mano per fare
esercizio. Le cose lasciate in sospeso non sono necessarie per il crack fine a
se stesso ma sono il miglior esercizio per imparare qcosa di Reverse
Engeneering.

Orbene, carichiamo l'eseguibile (CerTuS.exe) in VC++ e diamo un Trace Into
(F11) per ritrovarci nel codicillo asm. Ecco cosa si vede :

005488DC 55 push ebp
005488DD 8B EC mov ebp,esp
005488DF 83 C4 EC add esp,0ECh
005488E2 B8 04 84 54 00 mov eax,548404h
005488E7 E8 34 DF EB FF call 00406820 <- Chiamata sospetta
005488EC A1 8C B5 54 00 mov eax,[0054B58C]
005488F1 8B 00 mov eax,dword ptr [eax]
005488F3 E8 80 FF EB FF call 00408878
005488F8 84 C0 test al,al
005488FA 74 07 je 00548903
005488FC 33 C0 xor eax,eax
005488FE E8 11 B3 EB FF call 00403C14
00548903 E8 7C F8 EF FF call 00448184
.
.

Carichiamo CerTuS.exe anche nel WDasm, cosintanto che debugghiamo il
disassembler fa il suo lavoro (piuttosto lunghetto in questo caso).
Siccome il programma non ancora scaduto, conviene farsi un'idea del suo
funzionamento prima di alterare il clock di sistema per vedere cosa succede. Si
parte con uno Step Over (F10), e la prima cosa che salta all' occhio che la
chiamata 'CALL 00406820' decisamente pesante, e tra altre cose si preoccupa di
visualizzare la splash form di apertura. Visto che il controllo rimane in questa
prima parte di programma conveniente continuare il trace. E' abbastanza facile
intuire che l'istruzione che lancia il programma vero e proprio compresa nelle
:

.
.
005489BA 8B 00 mov eax,dword ptr [eax]
005489BC E8 2B 1C EE FF call 0042A5EC <- programma principale
005489C1 E8 F2 5D F5 FF call 0049E7B8 <-|
005489C6 E8 31 B1 EB FF call 00403AFC <--Routines di uscita
005489CB 00 FF add bh,bh
005489CD FF ???
.
.

Il programma vero e proprio viene lanciato da 'CALL 0042A5EC', il quale ci
presenta una form con i soliti disclaimer e soprattutto i giorni rimanenti.
Premendo 'Esci' (non era meglio 'Entra'? bahh!) il programma viene
effettivamente lanciato.
Per ora abbiamo givisto qcosa; intanto se il fido WDasm stato lanciato con
sufficiente anticipo dovrebbe aver prodotto il disassemblato del programma,
pronto per le solite ispezioni. Lasciamo tutto cose premuriamoci di portare
l'orologio di sistema avanti di 2 mesi, tanto per gradire.
Questa volta eseguendo normalmente CerTus veniamo subito bloccati da una dialog
che ci informa gentilmente che il periodo di prova terminato. Ma pensa te...
Torniamo al debugger e ricominciamo dall'inizio per vedere questa volta dove si
cela la trappola, ripartendo con F11; la porzione di codice iniziale sempre la
stessa, ma quando eseguiamo passo passo (F10) le istruzioni scopriamo che gi all' indirizzo 005488E7 contenente la 'CALL 00406820' viene effettuato il check.
Bene, se non altro sappiamo dove andare a parare. Restartiamo il programma e
tracciamo la 'CALL 00406820' con F11, il codice riportato qui sotto :

.
.
00406820 50 push eax
00406821 6A 00 push 0
00406823 E8 F8 FE FF FF call 00406720
00406828 BA 00 91 54 00 mov edx,549100h
0040682D 52 push edx
0040682E 89 05 B8 C4 54 00 mov dword ptr ds:[54C4B8h],eax
00406834 89 42 04 mov dword ptr [edx+4],eax
00406837 E8 98 FF FF FF call 004067D4
0040683C 5A pop edx
0040683D 58 pop eax
0040683E E8 AD D1 FF FF call 004039F0 <- Qui chekka i giorni
00406843 C3 ret
.
.

come si nota subito la routine non contiente istruzioni di salto, quindi la
chiamata al check della scadenza del termine deve essere necessariamente in una
delle chiamate, e non ci resta che scoprirlo eseguendole una ad una. Arrivati al
'POP EAX' non ancora successo nulla, infatti basta eseguire (F10) la 'CALL
004039F0' che ecco come per magilla la nostra carissima messagebox che
nuovamente di fa notare che dobbiamo cacciare fuori i soldi :-) per cui il
caso di tracciare ulteriormente. A questo proposito potrebbe essere il caso di
settare un breakpoint alla locazione 0040683E per evitare la tiritera di trace
step, ad libitum.
Supponiamo di essere nuovamente in procinto di eseguire 'CALL 004039F0' ed
analizziamola kon F11; ecco la nuova porzione di codice risultante :

.
.
004039F0 89 05 88 C4 54 00 mov dword ptr ds:[54C488h],eax
004039F6 31 C0 xor eax,eax
004039F8 89 05 8C C4 54 00 mov dword ptr ds:[54C48Ch],eax
004039FE 89 15 90 C4 54 00 mov dword ptr ds:[54C490h],edx
00403A04 8B 42 04 mov eax,dword ptr [edx+4]
00403A07 89 05 20 C0 54 00 mov dword ptr ds:[54C020h],eax
00403A0D E8 D6 FE FF FF call 004038E8
00403A12 C6 05 24 C0 54 00 00 mov byte ptr ds:[54C024h],0
00403A19 E8 72 FF FF FF call 00403990
00403A1E C3 ret
.
.

con la stessa deduzione logica fatta in precedenza siamo portati a pensare che
il codice del check sia in una delle due call. Vi risparmio la fatica e vi dico
subito che il controllo viene effettuato eseguendo 'CALL 00403990'. Restartiamo
ancora (manca poco, coraggio!) e riportiamoci subito prima dell' esecuzione
della chamata, tracciamola con F11 ed ecco :

.
.
00403990 55 push ebp
00403991 8B EC mov ebp,esp
00403993 53 push ebx
00403994 56 push esi
00403995 57 push edi
00403996 A1 88 C4 54 00 mov eax,[0054C488]
0040399B 85 C0 test eax,eax
0040399D 74 4B je 004039EA
0040399F 8B 30 mov esi,dword ptr [eax]
004039A1 33 DB xor ebx,ebx
004039A3 8B 78 04 mov edi,dword ptr [eax+4]
004039A6 33 D2 xor edx,edx
.
.

mmh... Qui il gioco si fa duro, e noi che siamo dei duri dobbiamo per
definizione cominciare a giocare. Innanzitutto eliminiamo tutti i breakpoints
eventualmente impostati in precedenza e settiamone uno solo in esecuzione dell'
indirizzo 00403990. Fatto cio' cominciamo la nostra esplorazione del codice.
Eseguendo con F10 istruzione per istruzione si arriva a questa parte di codice
che abbastanza critica :

.
.
004039B6 7E 14 jle 004039CC
004039B8 8B 04 DF mov eax,dword ptr [edi+ebx*8]
004039BB 43 inc ebx
004039BC 89 1D 8C C4 54 00 mov dword ptr ds:[54C48Ch],ebx
004039C2 85 C0 test eax,eax
004039C4 74 02 je 004039C8
004039C6 FF D0 call eax
004039C8 3B F3 cmp esi,ebx
004039CA 7F EC jg 004039B8
004039CC 33 C0 xor eax,eax
.
.

eseguendo il codice passo passo si entra in un loop, mentre se lasciassimo
proseguire il programma (ve lo dico io ;-) fino 004039CC con un Run To...
vedremmo immancabilmente spuntare la solita messagebox. Che fare? Innanzitutto
bevetevi un Martini Cocktail o un Invisibile, perchfa bene (anche se col
crackin' c'entrano sega) dopodichconcentratevi sul codice. E' evidente che una
volta entrati nel loop la sola condizione di uscita rappresentata dalla
istruzione 'CMP ESI,EBX' seguita da un 'JG 004039B8' (per chi non lo sapesse JG
= Jump if Greater) che riporta l'esecuzione del programma indietro. Una occhiata
ai registri della CPU ci fa vedere ESI = 0000009A mentre EBX = 000000xx, con xx
un valore che dipende dalle volte che avete eseguito il ciclo. Infatti
inizialmente EBX vale zero e viene incrementato ('INC EBX') presumibilmente fino
a raggiungere e superare il valore di ESI (9A). All' indirizzo 004039C6 c'una
strana 'CALL EAX', che potrebbe spiegarci il senso di tanto ciclare :
evidentemente EAX viene caricato (MOV EAX,DWORD PTR [EDI+EBX*8]) con il valore
di una routine presa da una tabella di procedure (o di inizializzazione di
oggetti) tra cui evidentemente anche la parte di codice che controlla se siamo
ancora in trial period. Come potrete ben intuire se avessimo semplicemente
saltato tutto cio' il programma si sarebbe miseramente piantato (eheheh ve lo
giuro ;-) dato che manca tutta questa inizializzazione.

Visto che per come la vedo io siamo qui per imparare, vorrei che quello che ho
scritto qui sopra non venisse letto frettolosamente. Non capita spessissimo di
trovare un check nidificato in questa maniera, ma proprio per questo fate
bagaglio di questa esperienza per evitare tentativi di suicidio davanti a qcosa
di simile in futuro...

Questo purtroppo non ci dice nulla della soluzione del nostro problema, se non
che saremo costretti ad eseguire le istruzioni del ciclo fino a che 'CALL EAX'
non farcomparire il messagebox, in modo da prendere nota del valore di EAX al
fine di piazzarci un nuovo breakpoint.
Io ovviamente ho fatto cos ma se volete potete impostare un breakpoint sul
valore di EBX = 18h (esadecimale!) in quanto la chiamata al check viene fatta
proprio per EBX = 00000018 con il registro EAX = 00447FD4. Questo ci da molte
utili informazioni, poiche ora sappiamo con esattezza *dove* mettere il prossimo
breakpoint, cioappunto a 00447FD4. Quittiamo e restartiamo il programma fino
ad incontrare il breakpoint, dove troveremo :

.
.
00447FD4 55 push ebp
00447FD5 8B EC mov ebp,esp
00447FD7 33 C0 xor eax,eax
00447FD9 55 push ebp
00447FDA 68 22 80 44 00 push 448022h
00447FDF 64 FF 30 push dword ptr fs:[eax]
00447FE2 64 89 20 mov dword ptr fs:[eax],esp
00447FE5 83 2D 7C C7 54 00 01 sub dword ptr ds:[54C77Ch],1 <--Giorni
rimasti
00447FEC 73 26 jae 00448014 <------- Meno di zero ?
cattivello...
00447FEE E8 AD 1D FC FF call 00409DA0
00447FF3 D8 25 2C 80 44 00 fsub dword ptr ds:[44802Ch]
00447FF9 DD 1D 68 C7 54 00 fstp qword ptr ds:[54C768h]
00447FFF 9B wait
00448000 C7 05 78 C7 54 00 FF mov dword ptr ds:[54C778h],0FFFFFFFFh
0044800A E8 7D FA FF FF call 00447A8C
0044800F E8 88 F4 FF FF call 0044749C
00448014 33 C0 xor eax,eax <----- Piu' di zero ? Ok
proseguiamo!
00448016 5A pop edx
00448017 59 pop ecx
00448018 59 pop ecx
00448019 64 89 10 mov dword ptr fs:[eax],edx
0044801C 68 29 80 44 00 push 448029h
00448021 C3 ret
.
.

mi scuso se ho riportato questa valanga di codice macchina, ma siamo arrivati al
cuore della routine di check. Il succo di tutto il check sta in quel 'SUB DWORD
PTR DS:[54C77Ch],1', ovvero nel decremento di una variabile. l'istruzione
successiva 'JAE 00448014' fa in modo che il programma salti a 00448014 se la
variabile vale zero o piu' di zero (JAE = Jump if Above or Equal). Che mi venga
un accidente se quelli non sono i giorni rimasti! Se sono rimasti 0 giorni di
prova e ne tolgo uno la variabile contiene un numero negativo e la procedura non
salta. Tutto qui. La tentazione davvero forte e visto che comunque il
breakpoint ce lo siamo gimarcato, tantovale fare la prova. Eseguiamo fino al
salto condizionato e simuliamolo settando l' EIP appunto a 00448014. Se la
nostra teoria fosse esatta il programma non dovrebbe + mostrare la messagebox ma
proseguire indisturbato.
Se proviamo a lasciar andare il programma (F5 sotto VC++) in realtle cose non
sono cossemplici. La messagebox NON viene piu' visualizzata, viene
visualizzata la splashform di presentazione giusta, ma nonostante cio' il
programma esce. Evidentemente ci sono altri checks :-(
A questo punto la disperazione potrebbe avervi colto. "Ma come, un onesto
Reverse Engeneer si da' costanto da fare e poi il risultato tutto qui?
BWaaaaah" (segue pianto disperato).
In realta' questo crack presenta altre insidie, ed inoltre ha diverse possibili
'soluzioni' a seconda del livello di eleganza che si in grado di raggiungere.
Visto che in fondo questo un tutorial e che se foste in grado di fare tutto da
soli molto ma molto probabilmente non stareste perdendo tempo con il mio
scritto, vi dico brevemente come si arriva ad una soluzione (la piu' immediata e
meno elegante, quella di cui un purista non dovrebbe mai accontentarsi).
Riprendete in mano il debugger e settate un nuovo breakpoint proprio sotto la
prima chiamata in questo punto esatto :

.
.
005488DD 8B EC mov ebp,esp
005488DF 83 C4 EC add esp,0ECh
005488E2 B8 04 84 54 00 mov eax,548404h
005488E7 E8 34 DF EB FF call 00406820
005488EC A1 8C B5 54 00 mov eax,[0054B58C] <-- Breakpoint qui
005488F1 8B 00 mov eax,dword ptr [eax]
.
.

ora attivate entrambi i breakpoint trovati, questo appena inserito e quello che
interrompe il programma all' inizio della prima routine di check, ovvero
all'indirizzo 00447FD4. Con questi due BP impostati lanciate il programma (F5),
eseguite la routine di check fino al salto condizionato visto prima (il 'JAE
00448014'), saltate direttamente a 00448014 e date nuovamente F5. A questo punto
vi troverete proprio sotto la chiamata iniziale, nel corpo principale del
programma.
Se stepperete il programma (F10) da qui troverete che il programma stesso si
chiudereseguendo una malefica 'CALL 00403C14', e che la stessa chiamata ripetuta con lo stesso schema per ben quattro volte prima dell'inizio della
routine del programma :

.
.
005488F8 84 C0 test al,al
005488FA 74 07 je 00548903
005488FC 33 C0 xor eax,eax
005488FE E8 11 B3 EB FF call 00403C14 <--<<< Call Malefica
00548903 E8 7C F8 EF FF call 00448184
.
.
00548942 9E sahf
00548943 76 07 jbe 0054894C
00548945 33 C0 xor eax,eax
00548947 E8 C8 B2 EB FF call 00403C14 <--<<< Anche qui !
0054894C A1 78 B9 54 00 mov eax,[0054B978]
.
.
00548969 84 C0 test al,al
0054896B 75 07 jne 00548974
0054896D 33 C0 xor eax,eax
0054896F E8 A0 B2 EB FF call 00403C14 <--<<< E qui !
00548974 8B 0D 18 BA 54 00 mov ecx,dword ptr ds:[54BA18h]
.
.
005489AB 9E sahf
005489AC 76 07 jbe 005489B5
005489AE 33 C0 xor eax,eax
005489B0 E8 5F B2 EB FF call 00403C14 <--<<< E pure qui !
005489B5 A1 78 B9 54 00 mov eax,[0054B978]
.
.

Ok, riassumendo il lavoro fatto fino ad ora (uff...) per sperare di usare 'sto
benedetto programma oltre i 30 giorni del trial period dobbiamo modificare
*cinque* istruzioni di salto condizionato in altrettanti salti incondizionati
ovvero Jxx -> JMP.
Se volete provare con un hexeditor a cercare nel file eseguibile la sequenza di
bytes < 83 2D 7C C7 54 00 01 [73] 26 > e sostituire '73' con 'EB' (JAE con JMP
in poche parole) e poi tutte le varie sequenze dei 4 salti condizionati e
sostituite l'istruzione di salto incondizionato JMP (per inciso :
< 84 C0 [74] 07 33 C0 E8 11 > con 'EB' al posto di '74' ,
< 9E [76] 07 33 C0 E8 C8 > 'EB' al posto di '76',
< 84 C0 [75] 07 33 C0 E8 A0 > 'EB' al posto di '75' e infine
< 9E [76] 07 33 C0 E8 5F > 'EB' al posto di '76' ) e salvare il tutto, potrete
vedere che con somma gioia il programma FUNZIONA! La splash form e la prima
schermata riportano 0 giorni rimasti, ma uno potrebbe dire 'Ecchissenefrega' e
tanti saluti. Noi NO.
Questa come dicevo una soluzione perfettamente funzionante, relativamente poco
invasiva (5 bytes modificati su un file di oltre 2Mb) ma decisamente poco
elegante. Dato che siamo/siete qui per IMPARARE, cerchiamo di andare oltre
questa prima modifica.
Prima di tutto sarebbe il caso di esaminare cosa fa la chiamata 'CALL 00403C14'
che fa terminare il programma. Vi riporto il codice :

.
.
00403C14 89 05 30 C0 54 00 mov dword ptr ds:[54C030h],eax
00403C1A E9 DD FE FF FF jmp 00403AFC
00403C1F C3 ret
.
.

beh, che dire... invece che modificare le istruzioni di salto per fare in modo
che non venga eseguita questa chiamata si potrebbe + elegantemente (ed anche +
utilmente, vedi il mio tutorial sul dongle) inserire come prima istruzione un
bel 'RET', visto che comunque le istruzioni di salto condizionato viste in
precedenza puntano tutte all'istruzione successiva a 'CALL 00403C14'. Piazzando
un 'RET' all' indirizzo 00403C14 non bisogna dimenticarsi di noppare i bytes in
modo da riempire la lunghezza dell' istruzione fino a quella successiva (il NOP
rappresentato dal valore 90h).
Anche questa soluzione perfettamente funzionale, e ci evita di modificare i 4
salti condizionati modificando solamente una istruzione nella stessa CALL da
loro eseguita.
Puo' bastare? Per usare il programma si, certo. Per voi NO.
Ecco allora la parte del crack lasciata aperta :

* LA PARTE DEL CRACK LASCIATA APERTA *
(bel titolino vero ?:-)

Ok,si diceva che se lo scopo fosse stato un crack fine a se stesso ce ne sarebbe
stato gid' avanzo. Siccome noi siamo gente ONESTISSIMA e reversiamo i
programmi al solo scopo di imparare a debuggare i nostri (cazzo quasi quasi ci
credo pure io tanto che lo dico bene...) d' obbligo estendere i nostri
orizzonti oltre le barriere del conosciuto.
Voglio infatti lasciare in sospeso alcune migliorie, parte delle quali le ho
sperimentate personalmente, mentre altre mi sono venute in mente quando oramai
avevo chiuso l' R-FILE (Reverse File :-) e non avevo voglia di rifare tutto
daccapo. Di conseguenza alcune modifiche sono semplici da fare, altre mediamente
difficili, altre di difficoltsconosciuta a priori. Non vi dico niente in
anticipo altrimenti sareste tentati di provare solo quelle gisperimentate da
me. Sappiatemi dire ovviamente...

UNO) Eliminare completamente la form di apertura che ci annoia con quel suo
assurdo tasto ESCI (bahh!!);

UNObis) Eliminare di conseguenza la stessa form all'uscita del prg.

DUE) Modificare il programma in modo da continuare a sembrare shareware con
un tot di giorni mancanti alla scadenza anche dopo che il prg ha cessato
di funzionare;

TRE) Modificare il programma per fare in modo che il programma appaia
registrato a nome di qkuno (che ne so, RingZer0 Inc. :-) e si comporti di
conseguenza (il codice lo prevede gi basta attivarlo);

QUATTRO) In realtla chiamata che noi eliminiamo con il RET ('CALL 00403C14')
ha anche altre funzioni e non viene eseguita sempre tutte e 4 le volte
che compare : tracciatela e modificate il programma in modo che essa
non faccia terminare il programma (ovviamente in maniera piu' elegante
che con il RET iniziale!.

Alcune tracce : Prima di tutto non vi ho fatto aprire WDasm32 tanto per giocare,
di conseguenza utilizzatelo perchpuo' tornare molto utile per questa parte;
Il ciclo 'CALL EAX' che vi ho detto di analizzare con cura non finisce dopo il
check ma fa altre cose;
Non sempre c'una sola variabile per tenere traccia di un dato.






搜尋引擎讓我們程式搜尋結果更加完美
  • 如果您覺得該文件有幫助到您,煩請按下我
  • 如果您覺得該文件是一個一無是處的文件,也煩請按下我

  • 搜尋引擎該文件您看起來是亂碼嗎?您可以切換編碼方式試試看!ISO-8859-1 | latin1 | euc-kr | euc-jp | CP936 | CP950 | UTF-8 | GB2312 | BIG5 |
    搜尋引擎本文件可能涉及色情、暴力,按我申請移除該文件

    搜尋引擎網址長?按我產生分享用短址

    ©2024 JSEMTS

    https://tw.search.yahoo.com/search;_ylt=A8tUwYgkQU1YcXoAUE9r1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC10dwRncHJpZAMxWU5tY2FYMVFGQ2ZvUXZGN1N0bzVBBG5fcnNsdAMwBG5fc3VnZwMwBG9yaWdpbgN0dy5zZWFyY2gueWFob28uY29tBHBvcwMwBHBxc3RyAwRwcXN0cmwDBHFzdHJsAzQ4BHF1ZXJ5AyVFNiVBRCVBMSVFNiVBRCU4QyUyMCVFNSVCMCU4OCVFNiU4MyU4NSVFNSU5QyU5OAR0X3N0bXADMTQ4MTQ1Nzk3Ng--?p=%E6%AD%A1%E6%AD%8C+%E5%B0%88%E6%83%85%E5%9C%98&fr2=sb-top-tw.search&fr=yfp-t-900-tw&rrjfid=4853786 https://tw.search.yahoo.com/search;_ylt=A8tUwYgkQU1YcXoAUE9r1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC10dwRncHJpZAMxWU5tY2FYMVFGQ2ZvUXZGN1N0bzVBBG5fcnNsdAMwBG5fc3VnZwMwBG9yaWdpbgN0dy5zZWFyY2gueWFob28uY29tBHBvcwMwBHBxc3RyAwRwcXN0cmwDBHFzdHJsAzQ4BHF1ZXJ5AyVFNiVBRCVBMSVFNiVBRCU4QyUyMCVFNSVCMCU4OCVFNiU4MyU4NSVFNSU5QyU5OAR0X3N0bXADMTQ4MTQ1Nzk3Ng--?p=%E6%AD%A1%E6%AD%8C+%E5%B0%88%E6%83%85%E5%9C%98&fr2=sb-top-tw.search&fr=yfp-t-900-tw&rrjfid=5320366 https://tw.search.yahoo.com/search;_ylt=A8tUwYgkQU1YcXoAUE9r1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC10dwRncHJpZAMxWU5tY2FYMVFGQ2ZvUXZGN1N0bzVBBG5fcnNsdAMwBG5fc3VnZwMwBG9yaWdpbgN0dy5zZWFyY2gueWFob28uY29tBHBvcwMwBHBxc3RyAwRwcXN0cmwDBHFzdHJsAzQ4BHF1ZXJ5AyVFNiVBRCVBMSVFNiVBRCU4QyUyMCVFNSVCMCU4OCVFNiU4MyU4NSVFNSU5QyU5OAR0X3N0bXADMTQ4MTQ1Nzk3Ng--?p=%E6%AD%A1%E6%AD%8C+%E5%B0%88%E6%83%85%E5%9C%98&fr2=sb-top-tw.search&fr=yfp-t-900-tw&rrjfid=7939724 https://tw.search.yahoo.com/search;_ylt=A8tUwYgkQU1YcXoAUE9r1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC10dwRncHJpZAMxWU5tY2FYMVFGQ2ZvUXZGN1N0bzVBBG5fcnNsdAMwBG5fc3VnZwMwBG9yaWdpbgN0dy5zZWFyY2gueWFob28uY29tBHBvcwMwBHBxc3RyAwRwcXN0cmwDBHFzdHJsAzQ4BHF1ZXJ5AyVFNiVBRCVBMSVFNiVBRCU4QyUyMCVFNSVCMCU4OCVFNiU4MyU4NSVFNSU5QyU5OAR0X3N0bXADMTQ4MTQ1Nzk3Ng--?p=%E6%AD%A1%E6%AD%8C+%E5%B0%88%E6%83%85%E5%9C%98&fr2=sb-top-tw.search&fr=yfp-t-900-tw&rrjfid=1600748 https://tw.search.yahoo.com/search;_ylt=A8tUwZJ2QE1YaVcAUmFr1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC1zLXR3BGdwcmlkAwRuX3JzbHQDMARuX3N1Z2cDMARvcmlnaW4DdHcuc2VhcmNoLnlhaG9vLmNvbQRwb3MDMARwcXN0cgMEcHFzdHJsAwRxc3RybAM4NARxdWVyeQMlRTglQjYlODUlRTUlOEYlQUYlRTYlODQlOUIlRTclOUElODQlRTUlQUYlQjYlRTUlQUYlQjYlMjAlRTglODMlQTElRTUlQUUlODklRTUlQTglOUMEdF9zdG1wAzE0ODE0NTc3OTM-?p=%E8%B6%85%E5%8F%AF%E6%84%9B%E7%9A%84%E5%AF%B6%E5%AF%B6+%E8%83%A1%E5%AE%89%E5%A8%9C&fr2=sb-top-tw.search&fr=yfp-t-900-s-tw&rrjfid=1858995 https://tw.search.yahoo.com/search;_ylt=A8tUwYgkQU1YcXoAUE9r1gt.;_ylc=X1MDMjExNDcwNTAwMwRfcgMyBGZyA3lmcC10LTkwMC10dwRncHJpZAMxWU5tY2FYMVFGQ2ZvUXZGN1N0bzVBBG5fcnNsdAMwBG5fc3VnZwMwBG9yaWdpbgN0dy5zZWFyY2gueWFob28uY29tBHBvcwMwBHBxc3RyAwRwcXN0cmwDBHFzdHJsAzQ4BHF1ZXJ5AyVFNiVBRCVBMSVFNiVBRCU4QyUyMCVFNSVCMCU4OCVFNiU4MyU4NSVFNSU5QyU5OAR0X3N0bXADMTQ4MTQ1Nzk3Ng--?p=%E6%AD%A1%E6%AD%8C+%E5%B0%88%E6%83%85%E5%9C%98&fr2=sb-top-tw.search&fr=yfp-t-900-tw&rrjfid=6492241