له تاریخ څخه دمخه
دا داسې پیښ شوي چې سرور د ransomware ویروس لخوا برید شوی و ، کوم چې د "خوشحاله حادثې" په واسطه په یو څه برخه کې د .ibd فایلونه (د innodb جدولونو خام ډیټا فایلونه) پاتې شول ، مګر په ورته وخت کې په بشپړ ډول د .fpm فایلونه کوډ کړل (. د جوړښت فایلونه). په دې حالت کې، .idb ویشل کیدی شي:
- د معیاري وسیلو او لارښودونو له لارې د بیا رغونې تابع. د داسې قضیو لپاره، یو غوره دی
شي ; - په جزوی توګه کوډ شوی میزونه. ډیری وختونه دا لوی میزونه دي، د کوم لپاره (لکه څنګه چې زه پوهیږم) برید کونکي د بشپړ کوډ کولو لپاره کافي RAM نه درلود؛
- ښه ، په بشپړ ډول کوډ شوي میزونه چې نشي بحال کیدی.
دا ممکنه وه چې معلومه کړئ چې میزونه د کوم اختیار سره تړاو لري په ساده ډول د مطلوب کوډ کولو لاندې په هر متن مدیر کې په خلاصولو سره (زما په قضیه کې دا UTF8 دی) او په ساده ډول د متن ساحو شتون لپاره فایل لیدل ، د مثال په توګه:
همچنان ، د فایل په پیل کې تاسو کولی شئ د 0 بایټ لوی شمیر وګورئ ، او ویروسونه چې د بلاک کوډ کولو الګوریتم کاروي (تر ټولو عام) معمولا دوی هم اغیزه کوي.
زما په قضیه کې، برید کونکو د هر کوډ شوي فایل په پای کې د 4 بایټ تار (1، 0، 0، 0) پریښود، کوم چې دا کار ساده کړی. د غیر انتفاعي فایلونو لټون کولو لپاره، سکریپټ کافی و:
def opened(path):
files = os.listdir(path)
for f in files:
if os.path.isfile(path + f):
yield path + f
for full_path in opened("C:somepath"):
file = open(full_path, "rb")
last_string = ""
for line in file:
last_string = line
file.close()
if (last_string[len(last_string) -4:len(last_string)]) != (1, 0, 0, 0):
print(full_path)
په دې توګه، دا معلومه شوه چې د لومړي ډول پورې اړوند فایلونه ومومئ. په دوهم کې ډیری لاسي کار شامل دی، مګر هغه څه چې وموندل شول لا دمخه کافي وو. هرڅه به سم وي، مګر تاسو باید پوه شئ په بشپړ ډول دقیق جوړښت او (البته) یوه قضیه راپورته شوه چې زه باید په مکرر ډول بدلیدونکي میز سره کار وکړم. هیڅوک په یاد نه دي چې ایا د ساحې ډول بدل شوی یا نوی کالم اضافه شوی.
وائلډز ښار، له بده مرغه، د داسې یوې قضیې سره مرسته نشي کولی، له همدې امله دا مقاله لیکل کیږي.
نقطې ته ورسیږئ
د 3 میاشتو دمخه د میز جوړښت شتون لري چې د اوسني سره سمون نه لري (احتمالا یو ساحه، او ممکن نور). د جدول جوړښت:
CREATE TABLE `table_1` (
`id` INT (11),
`date` DATETIME ,
`description` TEXT ,
`id_point` INT (11),
`id_user` INT (11),
`date_start` DATETIME ,
`date_finish` DATETIME ,
`photo` INT (1),
`id_client` INT (11),
`status` INT (1),
`lead__time` TIME ,
`sendstatus` TINYINT (4)
);
په دې حالت کې، تاسو اړتیا لرئ چې استخراج کړئ:
id_point
int(11);id_user
int(11);date_start
DATETIME;date_finish
DATETIME
د بیا رغولو لپاره، د .ibd فایل یو بایټ بایټ تحلیل کارول کیږي، وروسته یې د لوستلو وړ بڼه بدلوي. له هغه ځایه چې موږ ورته اړتیا لرو د موندلو لپاره ، موږ یوازې د ډیټا ډولونو تحلیل ته اړتیا لرو لکه int او ډیټاټایم ، مقاله به یوازې دوی تشریح کړي ، مګر ځینې وختونه به موږ د ډیټا نورو ډولونو ته هم مراجعه وکړو ، کوم چې کولی شي په نورو ورته پیښو کې مرسته وکړي.
ستونزه 1: د DATETIME او TEXT ډولونو سره ساحې NULL ارزښتونه لري، او دوی په ساده ډول په فایل کې پریښودل شوي، د دې له امله، زما په قضیه کې د بیا رغونې لپاره جوړښت ټاکل ممکن نه و. په نوي کالمونو کې، اصلي ارزښت ناپاک و، او د راکړې ورکړې یوه برخه د innodb_flush_log_at_trx_commit = 0 ترتیب کولو له امله له لاسه ورکولی شي، نو د جوړښت ټاکلو لپاره اضافي وخت باید مصرف شي.
ستونزه 2: دا باید په پام کې ونیول شي چې د DELETE له لارې حذف شوي قطارونه به ټول په ibd فایل کې وي، مګر د ALTER TABLE سره به د دوی جوړښت نوي نشي. د پایلې په توګه، د معلوماتو جوړښت کولی شي د فایل له پیل څخه تر پای پورې توپیر ولري. که تاسو ډیری وختونه د اصلاح میز کاروئ، نو تاسو احتمال نلري چې د داسې ستونزې سره مخ شئ.
پاملرنه وکړئد DBMS نسخه د معلوماتو ذخیره کولو طریقه اغیزه کوي، او دا مثال ممکن د نورو لویو نسخو لپاره کار ونکړي. زما په قضیه کې، د mariadb 10.1.24 وینډوز نسخه کارول شوې وه. همچنان ، که څه هم په mariadb کې تاسو د InnoDB جدولونو سره کار کوئ ، په حقیقت کې دوی دي
د فایل تحلیل
په python کې، د ډاټا ډول
د ډیری ibd فایلونو له لیدو وروسته ، تاسو لاندې موندلی شئ:
سربیره پردې ، که تاسو فایل د دې کلیمو لخوا ویشئ ، نو تاسو به ډیری حتی د ډیټا بلاکونه ترلاسه کړئ. موږ به انفیمیم د ویشونکي په توګه وکاروو.
table = table.split("infimum".encode())
یو په زړه پوری مشاهده: د میزونو لپاره د لږ مقدار ډیټا سره، د انفیمیم او سپیمیم ترمنځ په بلاک کې د قطارونو شمیر ته اشاره کوي.
- د لومړي قطار سره د ازموینې میز
- د 2 قطارونو سره د ازموینې میز
د قطار سرې جدول [0] پریښودل کیدی شي. د دې له لیدو وروسته ، زه لاهم نشم کولی د خام میز ډیټا ومومئ. ډیری احتمال، دا بلاک د شاخصونو او کیلي ذخیره کولو لپاره کارول کیږي.
د جدول [1] سره پیل کول او په عددي صف کې ژباړل ، تاسو دمخه ځینې نمونې لیدلی شئ ، یعنې:
دا int ارزښتونه دي چې په تار کې زیرمه شوي. لومړی بایټ په ګوته کوي چې ایا شمیره مثبته ده که منفي. زما په قضیه کې، ټولې شمیرې مثبت دي. د پاتې 3 بایټس څخه، تاسو کولی شئ د لاندې فنکشن په کارولو سره شمیره وټاکئ. سکریپټ:
def find_int(val: str): # example '128, 1, 2, 3'
val = [int(v) for v in val.split(", ")]
result_int = val[1]*256**2 + val[2]*256*1 + val[3]
return result_int
د مثال په توګه، 128، 0، 0، 1 = 1، یا 128، 0، 75، 108 = 19308.
جدول د اتومات زیاتوالي سره لومړنۍ کیلي درلوده، او دا دلته هم موندل کیدی شي
د ازموینې جدولونو څخه د معلوماتو پرتله کولو سره ، دا څرګنده شوه چې د DATETIME اعتراض 5 بایټ لري او د 153 سره پیل شوی (ډیری احتمال د کلني وقفې په ګوته کوي). څرنګه چې د DATTIME حد له '1000-01-01' څخه '9999-12-31' پورې دی، زه فکر کوم چې د بایټونو شمیر ممکن توپیر ولري، مګر زما په قضیه کې، ډاټا د 2016 څخه تر 2019 پورې موده کې راځي، نو موږ به فرض کړو دا 5 بایټ کافی دی.
د ثانیو پرته د وخت ټاکلو لپاره، لاندې دندې لیکل شوي. سکریپټ:
day_ = lambda x: x % 64 // 2 # {x,x,X,x,x }
def hour_(x1, x2): # {x,x,X1,X2,x}
if x1 % 2 == 0:
return x2 // 16
elif x1 % 2 == 1:
return x2 // 16 + 16
else:
raise ValueError
min_ = lambda x1, x2: (x1 % 16) * 4 + (x2 // 64) # {x,x,x,X1,X2}
دا ممکنه نه وه چې د کال او میاشتې لپاره د فعال فعالیت لیکلو لپاره، نو ما یې هیک کړی و. سکریپټ:
ym_list = {'2016, 1': '153, 152, 64', '2016, 2': '153, 152, 128',
'2016, 3': '153, 152, 192', '2016, 4': '153, 153, 0',
'2016, 5': '153, 153, 64', '2016, 6': '153, 153, 128',
'2016, 7': '153, 153, 192', '2016, 8': '153, 154, 0',
'2016, 9': '153, 154, 64', '2016, 10': '153, 154, 128',
'2016, 11': '153, 154, 192', '2016, 12': '153, 155, 0',
'2017, 1': '153, 155, 128', '2017, 2': '153, 155, 192',
'2017, 3': '153, 156, 0', '2017, 4': '153, 156, 64',
'2017, 5': '153, 156, 128', '2017, 6': '153, 156, 192',
'2017, 7': '153, 157, 0', '2017, 8': '153, 157, 64',
'2017, 9': '153, 157, 128', '2017, 10': '153, 157, 192',
'2017, 11': '153, 158, 0', '2017, 12': '153, 158, 64',
'2018, 1': '153, 158, 192', '2018, 2': '153, 159, 0',
'2018, 3': '153, 159, 64', '2018, 4': '153, 159, 128',
'2018, 5': '153, 159, 192', '2018, 6': '153, 160, 0',
'2018, 7': '153, 160, 64', '2018, 8': '153, 160, 128',
'2018, 9': '153, 160, 192', '2018, 10': '153, 161, 0',
'2018, 11': '153, 161, 64', '2018, 12': '153, 161, 128',
'2019, 1': '153, 162, 0', '2019, 2': '153, 162, 64',
'2019, 3': '153, 162, 128', '2019, 4': '153, 162, 192',
'2019, 5': '153, 163, 0', '2019, 6': '153, 163, 64',
'2019, 7': '153, 163, 128', '2019, 8': '153, 163, 192',
'2019, 9': '153, 164, 0', '2019, 10': '153, 164, 64',
'2019, 11': '153, 164, 128', '2019, 12': '153, 164, 192',
'2020, 1': '153, 165, 64', '2020, 2': '153, 165, 128',
'2020, 3': '153, 165, 192','2020, 4': '153, 166, 0',
'2020, 5': '153, 166, 64', '2020, 6': '153, 1, 128',
'2020, 7': '153, 166, 192', '2020, 8': '153, 167, 0',
'2020, 9': '153, 167, 64','2020, 10': '153, 167, 128',
'2020, 11': '153, 167, 192', '2020, 12': '153, 168, 0'}
def year_month(x1, x2): # {x,X,X,x,x }
for key, value in ym_list.items():
key = [int(k) for k in key.replace("'", "").split(", ")]
value = [int(v) for v in value.split(", ")]
if x1 == value[1] and x2 // 64 == value[2] // 64:
return key
return 0, 0
زه ډاډه یم چې که تاسو لږ وخت مصرف کړئ، دا غلط فهم سم کیدی شي.
بل، یو فنکشن چې د تار څخه د نیټې وخت اعتراض بیرته راګرځوي. سکریپټ:
def find_data_time(val:str):
val = [int(v) for v in val.split(", ")]
day = day_(val[2])
hour = hour_(val[2], val[3])
minutes = min_(val[3], val[4])
year, month = year_month(val[1], val[2])
return datetime(year, month, day, hour, minutes)
د int، int، datetime، datetime څخه په مکرر ډول تکرار شوي ارزښتونو کشف کولو لپاره اداره شوي ، داسې ښکاري چې دا هغه څه دي چې تاسو ورته اړتیا لرئ. سربیره پردې، دا ډول ترتیب په هره کرښه کې دوه ځله نه تکرار کیږي.
د منظم بیان په کارولو سره، موږ اړین معلومات پیدا کوو:
fined = re.findall(r'128, d*, d*, d*, 128, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*', int_array)
مهرباني وکړئ په یاد ولرئ کله چې د دې بیان په کارولو سره لټون کول ، دا به امکان ونلري چې په اړینو برخو کې د NULL ارزښتونه وټاکي ، مګر زما په قضیه کې دا مهم ندي. بیا موږ د هغه څه له لارې ځو چې موږ په لوپ کې وموندل. سکریپټ:
result = []
for val in fined:
pre_result = []
bd_int = re.findall(r"128, d*, d*, d*", val)
bd_date= re.findall(r"(153, 1[6,5,4,3]d, d*, d*, d*)", val)
for it in bd_int:
pre_result.append(find_int(bd_int[it]))
for bd in bd_date:
pre_result.append(find_data_time(bd))
result.append(pre_result)
په حقیقت کې، دا ټول دي، د پایلې سرې ډاټا هغه معلومات دي چې موږ ورته اړتیا لرو. ###PS.###
زه پوهیږم چې دا طریقه د هرچا لپاره مناسبه نه ده، مګر د مقالې اصلي هدف ستاسو د ټولو ستونزو د حل کولو پر ځای چټک عمل کول دي. زما په اند ترټولو سم حل به دا وي چې د سرچینې کوډ پخپله مطالعه پیل کړئ
په ځینو مواردو کې ، د فایل تحلیل کولو وروسته ، تاسو به وکولی شئ نږدې جوړښت وټاکئ او د پورته لینکونو څخه د یوې معیاري میتودونو په کارولو سره یې بحال کړئ. دا به ډیر سم وي او د لږو ستونزو لامل شي.
سرچینه: www.habr.com