ورود

View Full Version : قفل سی دی



benyamin_pc
چهارشنبه 20 دی 1385, 13:09 عصر
سلام
چطور میشه برنامه ای نوشت که اجازه به کپی شدن یه فقط فایل خاص از سی دی را نده؟

Best Programmer
چهارشنبه 20 دی 1385, 13:14 عصر
اگر بتونی بیشتر کاری که می خواهی انجام بدی را توضیح بدی و شرایط و پلت فرم را معرفی کنید.

benyamin_pc
پنج شنبه 21 دی 1385, 08:31 صبح
من خودم یه چیزایی پیدا کردم الان فقط می خواستم بدونم
با اسمبلی چطور میشه رو یه سکتور خاص اطلاعاتی نوشت و آن را خواند؟

greenway
جمعه 22 دی 1385, 21:24 عصر
من خودم یه چیزایی پیدا کردم الان فقط می خواستم بدونم
با اسمبلی چطور میشه رو یه سکتور خاص اطلاعاتی نوشت و آن را خواند؟

داستان سی دی خیلی مفصل تر از فلاپیه . باید کامندهای SCSI لازم برای باز کردن یک فصل جدید ، تغییر مد رایت ، رایت ، بستن فصل جدید رو به درایو ارسال کنید. بعد اونوقت سی دی شماره سکتورهاش رو از روی هدر بافر ، موقع رایت بهش میدن ، مثل فلاپی نیست . آخرش هم ، پیشنهاد میکنم دنبال اسمبلی نوشتنش زیاد نباشی ، چون یک عالمه وقت رو باید برای نوشتن توابعش بکنی ، آخرش هم کاربردی برات نداره ، با سی بنویس. برای ارسال کامند SCSI هم میتونی از ASPI یا SPTI استفاده کنی. ( سوالش کوتاهه ، ولی جوابش هفت تا کتابه که به Rainbow معروفند )

benyamin_pc
شنبه 23 دی 1385, 03:21 صبح
میشه با همون سی یه چیزیایی در مورد Write/Read رو یه سکتور خاص بگین؟
موقع کپی کردن اطلاعات رو فلاپی یا موقع رایت رو سی دی اطلاعات آیا تمام سکتورها مورد استفاده قرار می گیرند یا حتی تمام رکوردها؟

benyamin_pc
شنبه 23 دی 1385, 03:39 صبح
راستی وقتی یه چیزی از روی دیسکت یا سی دی کپی می کنیم با یه پورت خاصی این عمل انجام میشه؟

greenway
شنبه 23 دی 1385, 03:40 صبح
توصیه میکنم که در صورت تمایل ASPI SDK رو پیدا کنی .
کتاب CD Cracking Uncovered: Protection Against Unsanctioned CD Copying نوشته Kris Kaspersky هم چیز خوبیه . مثالهای خوبی هم با ASPI و هم با SPTI داره . اینجا رو هم ببین : http://club.cdfreaks.com/forumdisplay.php?f=52 و اینجا http://www.cdtool.pwp.blueyonder.co.uk/ و اینجا http://yates2k.net/cd.html

دیسکت یک چیزه ، سی دی یک چیز دیگه است ، دی وی دی یک چیز دیگر تره . سی دی و دی وی دی به هم شبیه هستند. اما فلاپی از پایه متفاوته . همه کارها توسط MiniPort درایورها انجام میشه که در معماری NT نهایتا از طریق HAL.DLL به Port فیزیکی مربوطه اش ارسال میشه . زمانی که درایو سی دی از نوع IDE باشه ، از همون پورتهای پیش فرض مثل 1F0 و 170 و اینا استفاده میشه ، چون وقتی ATAPI رو می ساختند، قبلش SCSI رو ساخته بودند و میشه کامندهای SCSI رو به سخت افزارهای ATAPI فرستاد. اما اگر درایو سی دی SCSI باشه ، مطمئنا پورتهاش هم فرق می کنه . داستان فلاپی هم که اصلا چیز دیگه است و کنترلرش هم چیز دیگه است و پورتهاش هم چیز دیگه هستند.

با اسمبلی یک چیزی شبیه این باید برای Eject بنویسی ،‌ هیچ کس از این جور کد خوشش نمیاد. کسی هم که می نویسه دیگه نمیاد اون در اختیار دیگران بذاره ! ( البته من بهش حق میدم ) :لبخندساده:



;************************************************* *****************
BeginProc EjectInvalidCDRom
PUSHA
STI
; Check The Busy Mode
CALL KWaitOnBusy
OR AL,AL
JZ EjectDone
CLI
; Check Drive Ready Mode
MOV dwkTimer,0FFFFFh
MOV DX,wkCDPort
ADD DX,7
EWaitLoop1:
IN AL,DX
AND AL,40h
JNZ EStep1J
OR dwkTimer,0
JZ EjectDone
DEC dword ptr dwkTimer
JMP EWaitLoop1
EStep1J:
; Select Device
CALL KSelectDevice
CALL KWaitOnBusy
; ; Setting nIEN
; MOV DX,wkCDCommandPort
; MOV AL,00000010B
; MOV AL,00001010B
; OUT DX,AL
; Set Packet Command
MOV DX,wkCDPort
ADD DX,7
MOV AL,0A0h
OUT DX,AL
; Wait 400 NS
DelayFor400NS wkCDCommandPort
; Wait For Busy
CALL KWaitOnBusy
; Wait For DRQ = 1
MOV dwkTimer,0FFFFFh
MOV DX,wkCDPort
ADD DX,7
EWaitLoop2:
IN AL,DX
AND AL,08h
JNZ EStep2J
OR dwkTimer,0
JZ EjectDone
DEC dword ptr dwkTimer
JMP EWaitLoop2
EStep2J:
; Send Packet Command, Eject
MOV DX,wkCDPort ; Send Packet
MOV AX,1Bh
OUT DX,AX ; 1
CALL WaitOneIOStep
XOR AX,AX
OUT DX,AX ; 2
CALL WaitOneIOStep
MOV AX,2
OUT DX,AX ; 3
CALL WaitOneIOStep
XOR AX,AX
OUT DX,AX ; 4
CALL WaitOneIOStep
XOR AX,AX
OUT DX,AX ; 5
CALL WaitOneIOStep
XOR AX,AX
OUT DX,AX ; 6
CALL WaitOneIOStep
MOV DX,wkCDCommandPort ; Read To Ignore the Results
IN AL,DX
; Poll Status , for Busy
CALL KWaitOnBusy
EjectDone:
POPA
RET
EndProc EjectInvalidCDRom

benyamin_pc
شنبه 23 دی 1385, 04:31 صبح
دستتون درد نکنه اون کد تو کارم می تونه راهنماییم کنه اما میشه بگین


موقع کپی کردن اطلاعات رو فلاپی یا موقع رایت رو سی دی
اطلاعات آیا تمام سکتورها مورد استفاده قرار می گیرند یا حتی تمام رکوردها؟

یه جیز دیگه میشه برنامه ای ساخت که با قرار دادن اون تو درایو پورتی که برای کار کپی کردن اطلاعات از روی سی دی مورد استفاده قرار می گیره رو بست؟تا دیگه نشه اونو کپی کرد؟

greenway
شنبه 23 دی 1385, 12:33 عصر
یه جیز دیگه میشه برنامه ای ساخت که با قرار دادن اون تو درایو پورتی که برای کار کپی کردن اطلاعات از روی سی دی مورد استفاده قرار می گیره رو بست؟تا دیگه نشه اونو کپی کرد؟

بله میشه ، اما بعدش دیگه خود ویندوز هم سی دی رو نمی تونه بخونه !‌ این برنامه هم به هیچ وجه در سطح Application Layer - Layer 3 ویندوز نیست و حتما باید به صورت Device Driver نوشته بشه.

Behrooz_CS
شنبه 23 دی 1385, 13:46 عصر
من یه مدت رفته بودم توی نخ شکستن قفل CD که مجبور شدم برم با اسمبلی و C تحت داس یه برنامه بنویسیم که سکتور به سکتور از روی CD بخونه و بعد بنویسمش توی یه فایل

من موفق به خواندن CD شدم اما از BadSector ها به سختی می گذشتم . بعد از یه مدتی هم بی خیالش شدم

حالا دیگه کدش بدردم نمی خوره ، برای همین براتون می زارمش اینجا تا بلکه یه نفر ازش استفاده کنه :چشمک:

#include <stdio.h>
#include <conio.h>
//#include <alloc.h>
//#include <stdlib.h>
#include <dos.h>
//#include <process.h>

#include <iostream.h>

//#include <
//================================================== ===============
//================================================== ===============
#define IdeCmdReg_R_Data 0
// Data Register
#define IdeCmdReg_W_Data 0 // Data Register
#define IdeCmdReg_R_Error 1 // Error Register
#define IdeCmdReg_W_Feature 1 // Feature Register
#define IdeCmdReg_R_SectCount 2 // Sector Count Register
#define IdeCmdReg_W_SectCount 2 // Sector Count Register
#define IdeCmdReg_R_Sector 3 // Sector Number or LBA Bits 0-7
#define IdeCmdReg_W_Sector 3 // Sector Number or LBA Bits 0-7
#define IdeCmdReg_R_Cylinder0 4 // Cylinder Bits 0-7 or LBA Bits 8-15
#define IdeCmdReg_W_Cylinder0 4 // Cylinder Bits 0-7 or LBA Bits 8-15
#define IdeCmdReg_R_Cylinder1 5 // Cylinder Bits 8-15 or LBA Bits 16-23
#define IdeCmdReg_W_Cylinder1 5 // Cylinder Bits 8-15 or LBA Bits 16-23
#define IdeCmdReg_R_DriveHead 6 // Drive & Head Bits or LBA Bits 24-27
#define IdeCmdReg_W_DriveHead 6 // Drive & Head Bits or LBA Bits 24-27
#define IdeCmdReg_R_Status 7
// Status Register
#define IdeCmdReg_W_Command 7 // Command Register

//; IDE Status Register Bits
#define IdeCmdReg_R_Status_BSY 0x80 // Bit 7
#define IdeCmdReg_R_Status_DRDY 0x40 // Bit 6
#define IdeCmdReg_R_Status_DWF 0x20 // Bit 5
#define IdeCmdReg_R_Status_DSC 0x10 // Bit 4
#define IdeCmdReg_R_Status_DRQ 0x08 // Bit 3
#define IdeCmdReg_R_Status_CORR 0x04 // Bit 2
#define IdeCmdReg_R_Status_IDX 0x02 // Bit 1
#define IdeCmdReg_R_Status_ERR 0x01 // Bit 0

//; [ ATA Commands ]

//; ATA PACKET INTERFACE Command
#define ATAPI_PKT_COMMAND 0x0A0 // Mandatory
//; ATAPI_IDENTIFY_DRIVE 0x0A1 ; Mandatory
//; ATAPI_SOFT_RESET 0x08 ; Mandatory
//; ATAPI_SERVICE 0x0A2 ; Optional

//; [ ATAPI Pkt Commands - as a parameter of ATA Command A0h ]
#define ATAPI_READ 0x28 // Operation Code

//================================================== ===============
//================================================== ===============
#define s_512 512
#define s_1k 1024
#define s_2k 2048
#define s_4k 4096
#define s_8k 8192
#define bufs s_2k

unsigned char Command=0;
unsigned int Port=0;
unsigned char Drive=0;
// Command Packet Buffer (CPB)
unsigned char CPB[12];
// Read Data Buffer (RDB)
unsigned char RDB[2048];
enum Status { Done , Busy , Error };

void Init_CPB();
void CD_Read_D();
Status ATAPI_Read();
unsigned CD_Read(char far *buf, unsigned si, unsigned di, unsigned num, unsigned DN=9);

char buf[bufs];
unsigned READ_SECTOR_DATA[512 * 0x30];

void main()
{
/*
unsigned i=0,j=0,k=1,h=0;

for(h=0 ; h<1 ; h++)
for(k=0x0 ; k<0x0ffff ; k++)
{
for(j=0; j<bufs ; j++)
buf[j] = 255; // == 0xff;

CD_Read(buf, h, k , 1, 9);
for(i=0 ; i<bufs ; i++)
{
//if(i/ 512.0f == i/512)
// getch();
if(buf[i] >= ' ')
cout << buf[i];
}
*/
clrscr();
CD_Read_D();
// getch();
getch();
}

int first=0;
unsigned CD_Read(char far *buf, unsigned _SI, unsigned _DI, unsigned num, unsigned DN)
{
unsigned sg=0,off=0;
sg = FP_SEG(buf);
off = FP_OFF(buf);
unsigned cf=0,_AX=0;
asm {
mov ax, 0x1508
mov cx, DN //CX = drive number (0=A: , 2=B: , 3=C: ,...)
mov si, _SI //SI:DI = starting sector number
mov di, _DI
mov es, sg //ES:BX -> buffer
mov bx, off
mov dx, num //DX = number of sectors to read
int 0x2f
mov _AX, ax
adc cf, 0
}
//if(!first) {
// clrscr();
cout << '\n'<< "AX=" << _AX << " * CF=" << cf << '\n';
// getchar();
// first = 1;
// }
return _AX;
}

#define AH (AX >> 8)
#define setAH(val) AX &= 0x00FF; AX |= (val << 8);
#define AL (AX & 0x0F)
#define setAL(val) AX &= 0xFF00; AX |= (val & 0xFF);
//enum Status { Done , Busy , Error };
void CD_Read_D()
{
Command = ATAPI_PKT_COMMAND;
Port = 0x170;
Drive = 0;
Status st = ATAPI_Read();
if(st == Done)
{
puts("Done.");
}
else if(st == Error)
puts("Error.");
else if(st == Busy)
puts("Busy.");
}

Status ATAPI_Read()
{
unsigned i=0;
unsigned AX=0, DX=0;
DX = IdeCmdReg_R_Status;
DX += Port;

for(i=0 ; i<0xFFFF ; i++)
{
setAL(inportb(DX));
AX &= IdeCmdReg_R_Status_BSY;
if(AX == 0)
break;
}
if(i == 0xFFFF)
return Busy;
// Write Ide command #1
DX = IdeCmdReg_W_DriveHead;
DX += Port;
AX = Drive;
AX |= 0x0EF; // Select Drive via Bit 4
outportb(DX , AL);

DX = IdeCmdReg_R_Status;
DX += Port;
for(i=0 ; i < 0xFFFF ; i++)
{
AX = inportb(DX);
AX &= 0x80; // Busy Bit
if(AX == 0)
break;
}
if(i == 0xFFFF) return Busy;

// Write Ide Command #2
DX = IdeCmdReg_W_Command;
DX += Port;
AX = 0;
setAL(Command);
outportb(DX , AL);

DX = IdeCmdReg_R_Status;
DX += Port;
for(i=0 ; i < 0xFFFF ; i++)
{
setAL(inportb(DX));
if( ( AX & 0x80) == 0) // NOT Busy
{
if( ( AX & 0x1) != 0 ) // IS Error
return Error;
if( ( AX & 0x08) != 0) // IS DRQ
break;
}
}
if(i == 0xFFFF) return Busy;

// Write Command Packet #1
DX = IdeCmdReg_R_Data;
DX += Port;
for(i=0 ; i<6 ; i++)
{
setAH( CPB[ i<<1 ] );
setAL( CPB[ (i<<1) + 1] );
outport(DX , AX);
}

DX = IdeCmdReg_R_Status;
DX += Port;
AX = 0;
// Read Status Reg #4
for(i=0 ; i < 0xFFFF ; i++)
{
AX = inportb(DX);
if( (AX & 0x80) == 0 ) // NOT Busy
{
if( (AX & 0x1) !=0 ) // Error
return Error;
if( (AX & 0x8) !=0 ) // DRQ
break;
}
}
if(i == 0xFFFF) return Busy;

DX = IdeCmdReg_R_Data;
DX += Port;
for(i=0 ; i<1024 ; i++)
{
AX = inport(DX);
RDB[ i<<1 ] = AH;
RDB[ (i<<1)+1 ] = AL;
}
printf("\n");
for(i=0 ; i<512 ; i++)
{
printf("%X", RDB[i]);
}

return Done;
}


void Init_CPB()
{
CPB[0] = 0x28; // operation code
CPB[1] = 0; // reserved
CPB[2] = 0x10;
CPB[3] = 0;
CPB[4] = 0;
CPB[5] = 0;
CPB[6] = 0; // reserved
CPB[7] = 1; // 100h --> 1 Sector
CPB[8] = 0;
CPB[9] = 0; // reserved
CPB[10] = 0;
CPB[11] = 0;
}

/* struct REGPACK r;

r.r_ax = 0x1508;

//CX = drive number (0=A:)
r.r_cx = DN; // j:

//SI:DI = starting sector number
r.r_si = si;
r.r_di = di;

//ES:BX -> buffer
r.r_es = FP_SEG(buf);
r.r_bx = FP_OFF(buf);

//DX = number of sectors to read
r.r_dx = num;

intr(0x2f , &r);
*/
/*struct CPB
{
char l1=0x28;
char l2=0;
} */


//Command_Packet_Buffer:
/*
db 0x28 //; Operation Code
db 0 //; Byte 1- Reserved
dd 0x10000000 //; Logical Block Address (16= ISO9660 Primary Volume Descriptor)
db 0 //; Byte 6 - Reserved
dw 0x0100 //; Transfer Lengt (1 sector)
db 0 //; Byte 9 to 11 are Reserved
db 0
db 0
*/

benyamin_pc
یک شنبه 24 دی 1385, 07:33 صبح
دستتون درد نکنه اما اگه یکمم در مورد برنامه توضیح بدین دیگه خیلی بهتر میشه

Behrooz_CS
یک شنبه 24 دی 1385, 18:10 عصر
من این برنامه را 3 سال پیش نوشتم !

الان هیچی ازش یادم نیست که بخوام براتون توضیح بدم ، شرمنده .