Ajuda - Busca - Membros - Calendário
Versão Completa: PlayStation 2 Game ICO Violates the GPL
Hangar Network Forum > Miscelânea > Hangarix
Yertzer
Uma das bibliotecas utilizadas na produção do jogo é gpl, portanto isso obrigaria que todo o jogo tivesse o código aberto.
Esse jogo é muito bom. Acham que o Stallman se intromete nisso?

http://games.slashdot.org/article.pl?sid=07/11/28/0328215

A prova:
http://astrange.ithinksw.net/ico/
Psycopata
Eu não entendi nada dessa prova, hehehehe. O que eu fiquei me perguntando é para que alguém teria o trabalho de fazer engenharia reversa num jogo.


Deus, tenha pena de mim, não faça otárias argumentarem que o cara queria apenas aprender! NÂo queria mesmo. NO nível dele, ele nada no jogo poderia ensinar algo.

Provavelmente não faz parte de uma polícia que fica vigiando todo tipo de software, então pq ele estava mexendo com isso num jogo de videogame.


Bom, A licença GPL é livre, e obriga as pessoas a abrirem o código de quem usar biliotecas GPL, certo? Mas é a pergunta que eu fazia quando eu comecei a usar linux e o hangarix estava sendo criado: se o código é fechado (direito de quem desenvolve, respeite), como saber se eles não utilizaram indevidamente códigos abertos? É um risco inerente do código aberto, e não do fechado. Deve-se concientizer quem desenvolve, e não pregar ver um aloprado por LSD que todos os códigos devem ser abertos.

É o risco do código aberto, quando descobrir, denunciar. Mas olha, eu no lugar da Sony, dava um jeito de processar o cara por espionagem industrial. A Sony errou? Sim, mas um erro não justifica o outro. O cara que estava fuçando no Jogo tb errou. Pau nos dois.
Tristan.Gostosão
Acho que o motivo dele de analisar o jogo foi curiosidade. Curiosidade que lhe permitiu descobrir fortes indicios de quebra de licenca.
Psycopata
Sei.....
Johannes RS
eu não me lembro de ter lido q o cara tenha feito engenharia reversa. parece q ele de alguma forma encontrou uma chamada com uma coincidência fantástica.

qto ao teu argumento, psyco: quer dizer q se eu abrir um buraco no terreno do vizinho e lá encontrar meu cachorro morto e enterrado, ele vai poder me processar por ter aberto um buraco na propriedade privada dele pra provar que ele tinha cometido crime de "canicício" e "ocultação de cadáver"? Não consigo me lembrar agora, mas poderia jurar q tem critério jurídico q joga isso no chão. Se não estou errado, um in dubia pró réu daria conta (tu tem certeza q a sony quebrou a licensa, mas não tem certeza de q o cara tava tentando fazer engenharia reversa com o objetivo de criar um PRODUTO (pra uso pessoal não tem problema) e portanto não tem certeza de q o cara cometeu crime).

Eu sempre fui um pouco contra esse tipo de política. O cara conseguiu a prova? Ele matou, torturou, subornou, estuprou ou pqp pariu algo desse porte pra conseguir a prova? não, então o q interessa é a prova.

a situação só se inverte no caso de chantagem. e não é invete, mas um equilibra na minha opinião.

por exemplo, eu estou errado, ou tristan, se eu der um mero "more" num executável eu já corro risco de tropeçar com coisas interessantes? e NUNCA ninguém vai poder me acusar de engenharia reversa por fazê-lo. wink.gif
Psycopata
Quadno eu for para BSb eu vou terntar isso com os CDs de PS2 e XBOX360 para ver o que deve dar.


Bom, na prova, tem uma parte de engenharia reversa.



Quanto a questão do seu cachorro, é fácil fácil de ganhar. O seu vizinho alega que vc invadiu a propriedade dele (ganha alguma coisa com isso), que vc destruiu propriedade privada (ah, isso sim tem indenização), falso testemunho (acusou sem provas que ele matou o cachorro, detalhe, isso dá uma idenização fudida de danos morais). É simples, se vc não provar que o seu vizinho matou o cachoro, o seu vizinho alega isso ai tudo acima e vc leva uma surra desgraçada.

A mesma coisa, o que garate da Sony ter usado os mesmos nomes de função? É difícil? Nem tanto. Se os caras que programaram o jogo tem muitos acessos e contatos ocm essa biblioteca, mesmo que eles programem a suas próprias funções, ele podem dar os mesmo nomes, da mesma forma que todos usam o i como contador. Sim, claro, é um pouico improvavel, se não impossível dar o mesmo nome a todo um conjunto de junções, e incluisive à bilioteca. Se tiver diferença nos códigos, a Sony mostra isso e aproveita para processar o cara por ter fuchado onde não devia.

outra coisa:
QUOTE
Evidence

To follow along with this, you'll need:

* a copy of the US version of ICO. (the important bit is SCUS_971.13)
* a disassembler for PS2 binaries. IDA Pro (if you can get it, which you can't) and ps2dis work under Windows.
I don't know of any good ones for other OSes, but ee-objdump from this gcc toolchain kind of works.
* mblock.c and inflate.c from libarc's source.

Reverse-engineering (interesting)
First, check out these strings from the data section:

ios/inflate.c
incomplete literal tree
incomplete distance tree
ios/mblock.c

ICO, helpfully, has all its debug logging still in the release binary. Here we can see the names of two files from libarc. Note the space before "incomplete" in both strings; this indicates a really old version of zlib. Even find-zlib, which claims to go back to zlib 0.1, doesn't have these. (It also doesn't find any data tables.)

From inflate.c:

/*
Copyright © 2000 Masanao Izumo <mo@goice.co.jp>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/* inflate.c -- Not copyrighted 1992 by Mark Adler
version c10p1, 10 January 1993 */

/* You can do whatever you like with this source file, though I would
prefer that if you modify it and redistribute it that you include
comments to that effect with your name and the date. Thank you.
[The history has been moved to the file ChangeLog.]
*/

And:

/* build the decoding tables for literal/length and distance codes */
bl = lbits;
i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl, &decoder->pool);
if(bl == 0) /* no literals or lengths */
i = 1;
if(i)
{
if(i == 1)
fprintf(stderr, " incomplete literal tree\n");
reuse_mblock(&decoder->pool);
return -1; /* incomplete code set */
}
bd = dbits;
i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd, &decoder->pool);
if(bd == 0 && nl > 257) /* lengths but no distances */
{
fprintf(stderr, " incomplete distance tree\n");
reuse_mblock(&decoder->pool);
return -1;
}

if(i == 1) {
#ifdef PKZIP_BUG_WORKAROUND
i = 0;
#else
fprintf(stderr, " incomplete distance tree\n");
#endif
}
if(i)
{
reuse_mblock(&decoder->pool);
return -1;
}

libarc uses a very old copy of INFLATE with the same error messages.
Reverse-engineering (boring)

Now that we've seen that, it's time for MIPS assembly!
I'll be using ps2dis's output here.
The equivalent to fprintf() is located at 0x001A6E28 in the binary. It's been simplified - the first argument is missing, but I'll use the same name for clarity.

Searching for those error strings finds this:

jal $001a6e28 # 0013531c:0c069b8a v fprintf
addiu a0, a0, $6b10 # 00135320:24846b10 a0=" incomplete literal tree\n"
beq zero, zero, $0013540c # 00135324:10000039 v __0013540c
daddu a0, s0, zero # 00135328:0200202d
__0013532c: #
addiu v0, zero, $0006 # 0013532c:24020006 v0=$00000006
lui a3, $0028 # 00135330:3c070028 a3=$00280000
lui t0, $0028 # 00135334:3c080028 t0=$00280000
sll a0, v1, 2 # 00135338:00032080
lw a1, $0514(sp) # 0013533c:8fa50514
sw v0, $04fc(sp) # 00135340:afa204fc
addu a0, sp, a0 # 00135344:03a42021
addiu a3, a3, $0b20 # 00135348:24e70b20 a3=$00280b20
addiu t0, t0, $0b60 # 0013534c:25080b60 t0=$00280b60
daddu a2, zero, zero # 00135350:0000302d
addiu t1, sp, $04f8 # 00135354:27a904f8
addiu t2, sp, $04fc # 00135358:27aa04fc
jal $001336c0 # 0013535c:0c04cdb0 ^ FNC_001336c0
daddu t3, s0, zero # 00135360:0200582d
lw v1, $04fc(sp) # 00135364:8fa304fc
bne v1, zero, $00135394 # 00135368:1460000a v __00135394
daddu s4, v0, zero # 0013536c:0040a02d s4=$00000006
lw v1, $0510(sp) # 00135370:8fa30510
sltiu v0, v1, $0102 # 00135374:2c620102
bne v0, zero, $00135398 # 00135378:14400007 v __00135398
addiu v0, zero, $0001 # 0013537c:24020001 v0=$00000001
lui a0, $0055 # 00135380:3c040055 a0=$00550000
jal $001a6e28 # 00135384:0c069b8a v fprintf
addiu a0, a0, $6b30 # 00135388:24846b30 a0=" incomplete distance tree\n"
beq zero, zero, $0013540c # 0013538c:1000001f v __0013540c
daddu a0, s0, zero # 00135390:0200202d
__00135394: #
addiu v0, zero, $0001 # 00135394:24020001 v0=$00000001
__00135398: #
bne s4, v0, $001353a8 # 00135398:16820003 v __001353a8
lui a0, $0055 # 0013539c:3c040055 a0=$00550000
jal $001a6e28 # 001353a0:0c069b8a v fprintf
addiu a0, a0, $6b30 # 001353a4:24846b30 a0=" incomplete distance tree\n"

This calls fprintf three times, as you can see.

Now, let's do a Google Code Search for the errors. Almost all of these are the same — they're either commented out or there's only one call to each. The only different one is TiMidity++, which turns out to use libarc!

After the error message, all three paths jump to here:

__0013540c: #
jal $00136140 # 0013540c:0c04d850 v FNC_00136140
nop # 00135410:00000000
beq zero, zero, $00135434 # 00135414:10000007 v __00135434
addiu v0, zero, $ffff # 00135418:2402ffff v0=$ffffffff

which goes to:

FNC_00136140: #
addiu sp, sp, $ffd0 # 00136140:27bdffd0
sd s1, $0010(sp) # 00136144:ffb10010
sd ra, $0020(sp) # 00136148:ffbf0020
daddu s1, a0, zero # 0013614c:0080882d
sd s0, $0000(sp) # 00136150:ffb00000
lw s0, $0000(s1) # 00136154:8e300000
beq s0, zero, $00136184 # 00136158:1200000a v __00136184
ld ra, $0020(sp) # 0013615c:dfbf0020
daddu a0, s0, zero # 00136160:0200202d
nop # 00136164:00000000
__00136168: #
jal $00136060 # 00136168:0c04d818 ^ FNC_00136060
lw s0, $000c(s0) # 0013616c:8e10000c
bne s0, zero, $00136168 # 00136170:1600fffd ^ __00136168
daddu a0, s0, zero # 00136174:0200202d
[...]

and further to:

FNC_00136060: #
lw v0, $0004(a0) # 00136060:8c820004
sltiu v0, v0, $2001 # 00136064:2c422001
bne v0, zero, $00136078 # 00136068:14400003 v __00136078
lw v0, $9758(gp) # 0013606c:8f829758 v0=$00632048
j $00139598 # 00136070:0804e566 v FNC_00139598
lw a0, $0000(a0) # 00136074:8c840000
__00136078: #
sw a0, $9758(gp) # 00136078:af849758 [00632048]
jr ra # 0013607c:03e00008
sw v0, $000c(a0) # 00136080:ac82000c
nop # 00136084:00000000
__00136088: #
sw zero, $0004(a0) # 00136088:ac800004
jr ra # 0013608c:03e00008
sw zero, $0000(a0) # 00136090:ac800000
nop # 00136094:00000000

and finally:

FNC_00139598: #
addiu sp, sp, $fb70 # 00139598:27bdfb70
sd s5, $0450(sp) # 0013959c:ffb50450
daddu s5, a0, zero # 001395a0:0080a82d
sd ra, $0480(sp) # 001395a4:ffbf0480
lui a0, $0055 # 001395a8:3c040055 a0=$00550000
sd s7, $0470(sp) # 001395ac:ffb70470
sd s6, $0460(sp) # 001395b0:ffb60460
addiu a0, a0, $72d8 # 001395b4:248472d8 a0="mem:free "
sd s4, $0440(sp) # 001395b8:ffb40440
sd s3, $0430(sp) # 001395bc:ffb30430
sd s2, $0420(sp) # 001395c0:ffb20420
sd s1, $0410(sp) # 001395c4:ffb10410
jal $001a6e28 # 001395c8:0c069b8a v fprintf
sd s0, $0400(sp) # 001395cc:ffb00400
bne s5, zero, $00139618 # 001395d0:16a00011 v __00139618
addiu s1, s5, $fff0 # 001395d4:26b1fff0
lui a0, $0055 # 001395d8:3c040055 a0=$00550000
jal $001a6e28 # 001395dc:0c069b8a v fprintf
addiu a0, a0, $72e8 # 001395e0:248472e8 a0="null memory pointer\n"
break (00000) # 001395e4:0000000d
lui s0, $0055 # 001395e8:3c100055 s0=$00550000
lui a2, $0055 # 001395ec:3c060055 a2=$00550000
addiu s0, s0, $70e0 # 001395f0:261070e0 s0="ios/memory.c"
addiu a2, a2, $7300 # 001395f4:24c67300 a2="IOSFREE(): NULL MEMORY POINTER\n"
daddu a0, s0, zero # 001395f8:0200202d a0="ios/memory.c"
jal $001ad748 # 001395fc:0c06b5d2 v FNC_001ad748
addiu a1, zero, $0334 # 00139600:24050334 a1=$00000334
lui a2, $0063 # 00139604:3c060063 a2=$00630000
daddu a0, s0, zero # 00139608:0200202d a0="ios/memory.c"
addiu a2, a2, $20b8 # 0013960c:24c620b8 a2=$006320b8
beq zero, zero, $001399b8 # 00139610:100000e9 v __001399b8
addiu a1, zero, $0334 # 00139614:24050334 a1=$00000334
[...]

That last function sure looks like free() to me.
From mblock.c:

static void reuse_mblock1(MBlockNode *p)
{
if(p->block_size > MIN_MBLOCK_SIZE)
free(p);
else /* p->block_size <= MIN_MBLOCK_SIZE */
{
p->next = free_mblock_list;
free_mblock_list = p;
}
}

void reuse_mblock(MBlockList *mblock)
{
MBlockNode *p;

if((p = mblock->first) == NULL)
return; /* There is nothing to collect memory */

while(p)
{
MBlockNode *tmp;

tmp = p;
p = p->next;
reuse_mblock1(tmp);
}
init_mblock(mblock);
}

Assuming you can read MIPS assembly (and you can, right?) they're obviously the same code. The memory management code here (reuse_mblock()) is entirely original; nothing that uses zlib compression would have this, unless it used libarc.

I could go further, but pointing out more of the same control flow in a bunch of assembly text isn't really needed.

Instead, I wrote a tool to decompress ICO's data archive, using libarc. libarc's compressor (in deflate.c) uses the same DEFLATE algorithm as gzip, but doesn't store a gzip or zip header. Nevertheless, it decompresses all the files perfectly* without any messing with the compressed stream needed. Get it in the links below.
("advertise.pss" is an MPEG-2 video and will play in VLC, although it won't have sound.)

* It doesn't have a checksum, so it might not actually be perfect, but it doesn't error at least!

Não creio que isso saia num simples more
WiseDuck
Pff, as duas coisas que mais existem em TI é engenharia reversa e uso indevido/ilegal de códigos licenciados. Alias, acho um absurdo ser proibido fazer engenharia reversa, no que quer que seja.
Tristan.Gostosão
QUOTE(Psycopata @ Dec 1 2007, 05:29 AM) *
Não creio que isso saia num simples more

Mas é quase isso. O cara deu um objdump nos binários lá e achou uns nomes interessantes. Quem aqui nunca deu um objdump num binário proprietario? Se eu visse esses nomes e soubesse que a libarc tem esses mesmos arquivos eu com certeza faria o que ele fez em seguida. Que também não é nada que não dê para fazer numa tarde quando você empolga com algo que descobriu. Aí depois que ele já tinha praticamente certeza que tava rolando uma quebra de licença ali ele continuou a investigação. Sinceramente, não é nada tão complicado assim, quase não pode ser chamado de engenharia reversa.

Conheço gente da hangar que já fez coisa muito mais agressiva que isso aí e certamente não foi com o objetivo de fazer um software parecido. Querendo ou não, há pessoas que gostam de aprender e tem curiosidade sobre as coisas. Por isso que alguns de nós nos consideramos ciêntistas.
Psycopata
as tipo, depois que um arquivo compilado, os nomes de funções ainda permanecem???? No arquivo binário?

Johannes RS
por isso q eu pensei q more daria, psuco.

faz o seguinte: dá um grep no diretório onde tão só os objetos e o executável, dos nomes das variáveis até q tu usou. Vira e mexe aparece cada coisa q tu te espanta como é q ainda aparece. wink.gif

P.S.: o q faz o objdump????
Tristan.Gostosão
QUOTE(Psycopata @ Dec 1 2007, 06:11 PM) *
as tipo, depois que um arquivo compilado, os nomes de funções ainda permanecem???? No arquivo binário?

Como eles não removeram as tabelas de debug esse tipo de coisa fica lá. Número das linhas dos arquivos, etc. Se não ficasse, como o debugger saberia que linha do seu código C está sendo executada no binário?

QUOTE(Johannes RS @ Dec 1 2007, 06:21 PM) *
por isso q eu pensei q more daria, psuco.

faz o seguinte: dá um grep no diretório onde tão só os objetos e o executável, dos nomes das variáveis até q tu usou. Vira e mexe aparece cada coisa q tu te espanta como é q ainda aparece. wink.gif

P.S.: o q faz o objdump????

Ele só mostra as informações armazenadas no objeto, tabela de simbolos, código, headers, etc. Enfim, meta-informação do binário, mas ele também mostra um dump do assembly.
Psycopata
Mas tipo assim, tem uma parte naquela página que mostra o heap do processador. Isso vem no more? Aki em Goiânia eu naõ tenho linux, então não dá para fazer o teste




QUOTE(WiseDuck @ Dec 1 2007, 06:39 AM) *
Pff, as duas coisas que mais existem em TI é engenharia reversa e uso indevido/ilegal de códigos licenciados. Alias, acho um absurdo ser proibido fazer engenharia reversa, no que quer que seja.

Lógico que não. Vc gostaria que algum zé-mané fizesse engenharia reversa numa tecnologia sua que vc levou anos para desenvolver e que provavelmente garantiria o seu futuro? Nâo pode ser radical assim.
Tristan.Gostosão
QUOTE(Psycopata @ Dec 2 2007, 02:34 AM) *
Mas tipo assim, tem uma parte naquela página que mostra o heap do processador. Isso vem no more? Aki em Goiânia eu naõ tenho linux, então não dá para fazer o teste

Ele não mostra heap hora nenhuma, até porque heap do processador é uma expressão meio esquisita, ela não faz tanto sentido. O que o cara fez foi só usar aquele ps2dis que transforma o código binário nos nomes legiveis das instruções. Ele fez isso para confirmar suas suspeitas, que vieram do objdump.

QUOTE
Lógico que não. Vc gostaria que algum zé-mané fizesse engenharia reversa numa tecnologia sua que vc levou anos para desenvolver e que provavelmente garantiria o seu futuro? Nâo pode ser radical assim.

Isso aí não tem nada a ver, o usuário deveria ter direito de analisar o que tá rodando na máquina dele, o que ele comprou. Uma coisa é plagio e espionagem industrial, outra coisa bem diferente é tentar entender algo que você comprou.
Psycopata
É mais ai fica meio difícil de contralar se vão copior ou não.

Vou dar um exemplo, acho qeu vc nunca viu e nem procurou ver o código da ingeção eletrônica do seu carro (ou carro do seu pai). Vc não teria o direito de saber como aquilo foi desenvolvido para ter certeza que não tem um bug q possa fazer o seu carro parar justamente quando mais necessita dele?

É a mesma coisa com o software.
Tristan.Gostosão
QUOTE(Psycopata @ Dec 3 2007, 01:12 AM) *
É mais ai fica meio difícil de contralar se vão copior ou não.

Vou dar um exemplo, acho qeu vc nunca viu e nem procurou ver o código da ingeção eletrônica do seu carro (ou carro do seu pai). Vc não teria o direito de saber como aquilo foi desenvolvido para ter certeza que não tem um bug q possa fazer o seu carro parar justamente quando mais necessita dele?

É a mesma coisa com o software.

Eu adoraria saber o código e seu funcionamento, infelizmente não tenho muita coragem de ficar mexendo nessas coisas, uma vez que paguei caro e tenho certeza que acabaria com a garantia se mexesse. Mas video game é uma coisa muito mais acessível, eu nunca tive curiosidade de ficar olhando o que aqueles jogos de playstation usam nem nada, na verdade não tenho muita paciência para ficar estudando código fechado. Eu sinto que estudar programas fechados dá muito trabalho e o benefício é muito pequeno. Já há outras pessoas que acham divertido. Há, também, aqueles que não curtem estudar código livre, como eu faço. Mas esse não é o ponto. O ponto é só que o que o cara fez não é nada de outro mundo, qualquer um que conhecesse o código da biblioteca libarc e desse um dump no código do joguinho ia notar algo estranho. Na minha opinião o cara diz que fez engenharia reversa só por questão de ego, porque ele fez algo bem simples. Quem faz muito esse tipo de coisa é o pessoal do wine, mas eu não tenho paciência.
WiseDuck
QUOTE(Psycopata @ Dec 2 2007, 12:51 AM) *
Lógico que não. Vc gostaria que algum zé-mané fizesse engenharia reversa numa tecnologia sua que vc levou anos para desenvolver e que provavelmente garantiria o seu futuro? Nâo pode ser radical assim.

No meu caso, eu iria preferir não levar anos pra desenvolver, mas apenas fazer engenharia reversa em algo já existente e partir dali. E acharia (acho) normal que o concorrente então faça a engenharia reversa no meu pra fazer o novo dele.
Johannes RS
bom, essa outra questão é complicada.

especialmente pq, no qdiz respeito a tecnologia e software, mesmo q tu possa dizer q tem direito de patente (e, no caso das últimas, eu discordo), ela tem q ser por tempo curto, mais curto q o atual de preferência e sem efeito mickey mouse. smile.gif

após findado o período, as empresas deveríam fazer o q tem em qq patente: dizer claramente o q é o troço, mas não como elas fizeram. mais ou menos como uma molécula específica: elas não podem recusar nenhum detalhe do produto final de fora, mas podem esconder para sempre como foi q fizeram pra produzir a que eles vendíam. wink.gif
Psycopata
QUOTE(WiseDuck @ Dec 4 2007, 01:41 AM) *
No meu caso, eu iria preferir não levar anos pra desenvolver, mas apenas fazer engenharia reversa em algo já existente e partir dali. E acharia (acho) normal que o concorrente então faça a engenharia reversa no meu pra fazer o novo dele.



Credo, eu não
Psycopata
eu tentei fazer isso no dvd do xbox mas os arquivo não aparece sad.gif
Esta é uma versão simplificada de nosso conteúdo principal. Para ver a versão completa com maiores informações, formatação e imagens, por favor clique aqui.
Invision Power Board © 2001-2009 Invision Power Services, Inc.